New tests.
authorMarek Safar <marek.safar@gmail.com>
Wed, 19 Aug 2009 10:58:38 +0000 (10:58 -0000)
committerMarek Safar <marek.safar@gmail.com>
Wed, 19 Aug 2009 10:58:38 +0000 (10:58 -0000)
svn path=/trunk/mcs/; revision=140231

396 files changed:
ChangeLog
data/net_2_0/ChangeLog
data/net_2_0/DefaultWsdlHelpGenerator.aspx
mcs/build/common/ChangeLog
mcs/build/common/Consts.cs.in
mcs/class/ChangeLog
mcs/class/Makefile
mcs/class/Managed.Windows.Forms/System.Windows.Forms/AsyncMethodResult.cs
mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog
mcs/class/Managed.Windows.Forms/System.Windows.Forms/DataGrid.cs
mcs/class/Managed.Windows.Forms/System.Windows.Forms/DataGridViewCell.cs
mcs/class/Managed.Windows.Forms/System.Windows.Forms/SplitContainer.cs
mcs/class/Managed.Windows.Forms/System.Windows.Forms/ThemeWin32Classic.cs
mcs/class/Managed.Windows.Forms/System.Windows.Forms/ToolStripDropDownItem.cs
mcs/class/Managed.Windows.Forms/System.Windows.Forms/ToolStripItem.cs
mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIDriver.cs
mcs/class/Managed.Windows.Forms/Test/System.Windows.Forms/ChangeLog
mcs/class/Managed.Windows.Forms/Test/System.Windows.Forms/DataGridTest.cs
mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/BatchingImplBase.cs
mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ChangeLog
mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ConsoleLogger.cs
mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/TaskDatabase.cs
mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/TaskEngine.cs
mcs/class/Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/ChangeLog
mcs/class/Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/ProjectTest.cs
mcs/class/Microsoft.Build.Tasks/ChangeLog
mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks.dll.sources
mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/AssemblyResolver.cs
mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/ChangeLog
mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/PcFileCache.cs [new file with mode: 0644]
mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/ResolveAssemblyReference.cs
mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/ResolvedReference.cs
mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/TaskLoggingHelperExtension.cs
mcs/class/Microsoft.CSharp/Microsoft.CSharp.RuntimeBinder/CSharpBinder.cs [new file with mode: 0644]
mcs/class/Microsoft.CSharp/Microsoft.CSharp.RuntimeBinder/CSharpGetMemberBinder.cs
mcs/class/Microsoft.CSharp/Microsoft.CSharp.RuntimeBinder/CSharpInvokeBinder.cs
mcs/class/Microsoft.CSharp/Microsoft.CSharp.RuntimeBinder/CSharpInvokeMemberBinder.cs
mcs/class/Microsoft.CSharp/Microsoft.CSharp.RuntimeBinder/ChangeLog
mcs/class/Microsoft.CSharp/Microsoft.CSharp.dll.sources
mcs/class/Mono.Cecil/ChangeLog
mcs/class/Mono.Cecil/Mono.Cecil/BaseAssemblyResolver.cs
mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/ChangeLog
mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds.cs
mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds42.cs
mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds50.cs
mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds70.cs
mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds80.cs
mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/TdsConnectionPool.cs
mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/TdsDataColumnCollection.cs
mcs/class/System.Core/ChangeLog
mcs/class/System.Core/Microsoft.Win32.SafeHandles/ChangeLog [new file with mode: 0755]
mcs/class/System.Core/Microsoft.Win32.SafeHandles/SafePipeHandle.cs [new file with mode: 0644]
mcs/class/System.Core/System.Core.dll.sources
mcs/class/System.Core/System.IO.Pipes/AnonymousPipeClientStream.cs [new file with mode: 0644]
mcs/class/System.Core/System.IO.Pipes/AnonymousPipeServerStream.cs [new file with mode: 0644]
mcs/class/System.Core/System.IO.Pipes/ChangeLog [new file with mode: 0755]
mcs/class/System.Core/System.IO.Pipes/NamedPipeClientStream.cs [new file with mode: 0644]
mcs/class/System.Core/System.IO.Pipes/NamedPipeServerStream.cs [new file with mode: 0644]
mcs/class/System.Core/System.IO.Pipes/PipeAccessRights.cs [new file with mode: 0644]
mcs/class/System.Core/System.IO.Pipes/PipeAccessRule.cs [new file with mode: 0644]
mcs/class/System.Core/System.IO.Pipes/PipeAuditRule.cs [new file with mode: 0644]
mcs/class/System.Core/System.IO.Pipes/PipeDirection.cs [new file with mode: 0644]
mcs/class/System.Core/System.IO.Pipes/PipeInterfaces.cs [new file with mode: 0644]
mcs/class/System.Core/System.IO.Pipes/PipeOptions.cs [new file with mode: 0644]
mcs/class/System.Core/System.IO.Pipes/PipeSecurity.cs [new file with mode: 0644]
mcs/class/System.Core/System.IO.Pipes/PipeStream.cs [new file with mode: 0644]
mcs/class/System.Core/System.IO.Pipes/PipeStreamImpersonationWorker.cs [new file with mode: 0644]
mcs/class/System.Core/System.IO.Pipes/PipeTransmissionMode.cs [new file with mode: 0644]
mcs/class/System.Core/System.IO.Pipes/PipeUnix.cs [new file with mode: 0644]
mcs/class/System.Core/System.IO.Pipes/PipeWin32.cs [new file with mode: 0644]
mcs/class/System.Core/System.IO/ChangeLog [new file with mode: 0755]
mcs/class/System.Core/System.IO/HandleInheritability.cs [new file with mode: 0644]
mcs/class/System.Data/ChangeLog
mcs/class/System.Data/Mono.Data.SqlExpressions/ChangeLog
mcs/class/System.Data/Mono.Data.SqlExpressions/Comparison.cs
mcs/class/System.Data/System.Data.SqlClient/ChangeLog
mcs/class/System.Data/System.Data.SqlClient/SqlConnection.cs
mcs/class/System.Data/System.Data_test.dll.sources
mcs/class/System.Data/Test/Mono.Data.SqlExpressions/ChangeLog
mcs/class/System.Data/Test/Mono.Data.SqlExpressions/DateComparisonTest.cs [new file with mode: 0644]
mcs/class/System.Data/Test/Mono.Data.SqlExpressions/dateComparisonTest.xml [new file with mode: 0644]
mcs/class/System.Data/Test/ProviderTests/sql/ChangeLog
mcs/class/System.Data/Test/ProviderTests/sql/sqlserver7.sql [new file with mode: 0644]
mcs/class/System.Json/ChangeLog
mcs/class/System.Json/Makefile
mcs/class/System.Net/ChangeLog
mcs/class/System.Net/System.Net.NetworkInformation/ChangeLog [new file with mode: 0644]
mcs/class/System.Net/System.Net.NetworkInformation/NetworkChange_2_1.cs [new file with mode: 0644]
mcs/class/System.Net/System.Net.NetworkInformation/NetworkInterface_2_1.cs [new file with mode: 0644]
mcs/class/System.Net/net_2_1_raw_System.Net.dll.sources
mcs/class/System.ServiceModel.Web/System.ServiceModel.Web/ChangeLog
mcs/class/System.ServiceModel.Web/System.ServiceModel.Web/WebChannelFactory.cs
mcs/class/System.ServiceModel/ChangeLog
mcs/class/System.ServiceModel/System.ServiceModel.Channels/BodyWriter.cs
mcs/class/System.ServiceModel/System.ServiceModel.Channels/ChangeLog
mcs/class/System.ServiceModel/System.ServiceModel.Channels/DuplexChannelBase.cs
mcs/class/System.ServiceModel/System.ServiceModel.Channels/Message.cs
mcs/class/System.ServiceModel/System.ServiceModel.Channels/MessageHeader.cs
mcs/class/System.ServiceModel/System.ServiceModel.Channels/MessageHeaders.cs
mcs/class/System.ServiceModel/System.ServiceModel.Channels/MessageImpl.cs
mcs/class/System.ServiceModel/System.ServiceModel.Channels/PeerDuplexChannel.cs
mcs/class/System.ServiceModel/System.ServiceModel.Channels/ReplyChannelBase.cs
mcs/class/System.ServiceModel/System.ServiceModel.Channels/RequestChannelBase.cs
mcs/class/System.ServiceModel/System.ServiceModel.Channels/TcpChannelListener.cs
mcs/class/System.ServiceModel/System.ServiceModel.Channels/TcpDuplexSessionChannel.cs
mcs/class/System.ServiceModel/System.ServiceModel.Description/ChangeLog
mcs/class/System.ServiceModel/System.ServiceModel.Description/ContractDescription.cs
mcs/class/System.ServiceModel/System.ServiceModel.Description/DataContractSerializerOperationBehavior.cs
mcs/class/System.ServiceModel/System.ServiceModel.Description/MetadataExchangeClient.cs
mcs/class/System.ServiceModel/System.ServiceModel.Description/MetadataResolver.cs
mcs/class/System.ServiceModel/System.ServiceModel.Description/OperationContractGenerationContext.cs
mcs/class/System.ServiceModel/System.ServiceModel.Description/ServiceContractGenerator.cs
mcs/class/System.ServiceModel/System.ServiceModel.Description/ServiceDebugBehavior.cs
mcs/class/System.ServiceModel/System.ServiceModel.Description/ServiceMetadataBehavior.cs
mcs/class/System.ServiceModel/System.ServiceModel.Description/ServiceMetadataExtension.cs
mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/BaseMessagesFormatter.cs
mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/ChangeLog
mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/ChannelDispatcher.cs
mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/DefaultOperationInvoker.cs [new file with mode: 0644]
mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/EndpointDispatcher.cs
mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/IOperationInvoker.cs
mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/OperationInvokerHandler.cs
mcs/class/System.ServiceModel/System.ServiceModel.PeerResolvers/ChangeLog
mcs/class/System.ServiceModel/System.ServiceModel.PeerResolvers/IPeerConnectorContract.cs
mcs/class/System.ServiceModel/System.ServiceModel.dll.sources
mcs/class/System.ServiceModel/System.ServiceModel/AllEnums.cs
mcs/class/System.ServiceModel/System.ServiceModel/ChangeLog
mcs/class/System.ServiceModel/System.ServiceModel/ClientBase.cs
mcs/class/System.ServiceModel/System.ServiceModel/EndpointAddress.cs
mcs/class/System.ServiceModel/System.ServiceModel/OperationContextScope.cs
mcs/class/System.ServiceModel/System.ServiceModel/ServiceBehaviorAttribute.cs
mcs/class/System.ServiceModel/System.ServiceModel/ServiceHostBase.cs
mcs/class/System.ServiceModel/System.ServiceModel/ServiceRuntimeChannel.cs
mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/ChangeLog
mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/MessageTest.cs
mcs/class/System.Web.Extensions/System.Web.Configuration/ChangeLog [new file with mode: 0644]
mcs/class/System.Web.Extensions/System.Web.Configuration/ScriptingJsonSerializationSection.cs
mcs/class/System.Web.Extensions/System.Web.Script.Serialization/ChangeLog
mcs/class/System.Web.Extensions/System.Web.Script.Serialization/JavaScriptSerializer.cs
mcs/class/System.Web.Extensions/System.Web.Script.Serialization/JsonSerializer.cs
mcs/class/System.Web.Extensions/System.Web.Script.Services/ChangeLog
mcs/class/System.Web.Extensions/System.Web.Script.Services/LogicalTypeInfo.cs
mcs/class/System.Web.Extensions/Test/System.Web.Script.Serialization/ChangeLog
mcs/class/System.Web.Extensions/Test/System.Web.Script.Serialization/JavaScriptSerializerTest.cs
mcs/class/System.Web.Mvc/ChangeLog
mcs/class/System.Web.Mvc/Makefile
mcs/class/System.Web/ChangeLog
mcs/class/System.Web/Makefile
mcs/class/System.Web/System.Web.Compilation/AspGenerator.cs
mcs/class/System.Web/System.Web.Compilation/AspParser.cs
mcs/class/System.Web/System.Web.Compilation/BuildManagerDirectoryBuilder.cs
mcs/class/System.Web/System.Web.Compilation/ChangeLog
mcs/class/System.Web/System.Web.UI/ChangeLog
mcs/class/System.Web/System.Web.UI/ControlBuilder.cs
mcs/class/System.Web/System.Web_test.dll.sources
mcs/class/System.Web/Test/System.Web.Compilation/ChangeLog
mcs/class/System.Web/Test/System.Web.Compilation/TemplateControlCompilerTest.cs
mcs/class/System.Web/Test/mainsoft/NunitWeb/NunitWeb/Global.asax.cs [new file with mode: 0644]
mcs/class/System.Web/Test/mainsoft/NunitWeb/NunitWeb/Resources/Global.asax
mcs/class/System.Web/Test/mainsoft/NunitWeb/NunitWeb/Resources/Global.asax.cs [deleted file]
mcs/class/System.Web/Test/mainsoft/NunitWebResources/DuplicateControlsInClientComment.aspx [new file with mode: 0644]
mcs/class/System.Web/Test/mainsoft/NunitWebResources/NewlineInCodeExpression.aspx [new file with mode: 0644]
mcs/class/System.Web/Test/mainsoft/NunitWebResources/ServerControlInClientSideComment.aspx
mcs/class/System/ChangeLog
mcs/class/System/System.CodeDom/ChangeLog
mcs/class/System/System.CodeDom/CodeTypeReference.cs
mcs/class/System/System.Collections.Concurrent/BlockingCollection.cs [new file with mode: 0644]
mcs/class/System/System.Collections.Concurrent/ChangeLog [new file with mode: 0644]
mcs/class/System/System.Net/ChangeLog
mcs/class/System/System.Net/CookieCollection.cs
mcs/class/System/System.Net/CookieContainer.cs
mcs/class/System/System.Net/HttpWebRequest.cs
mcs/class/System/System.Net/NetworkCredential.cs
mcs/class/System/System.Net/NtlmClient.cs
mcs/class/System/System.Net/WebConnectionStream.cs
mcs/class/System/System.Text.RegularExpressions/ChangeLog
mcs/class/System/System.Text.RegularExpressions/Regex.cs
mcs/class/System/System.Text.RegularExpressions/parser.cs
mcs/class/System/System.Text.RegularExpressions/syntax.cs
mcs/class/System/System.Threading/Barrier.cs [new file with mode: 0644]
mcs/class/System/System.Threading/ChangeLog
mcs/class/System/System.dll.sources
mcs/class/System/System_test.dll.sources
mcs/class/System/Test/System.CodeDom/ChangeLog
mcs/class/System/Test/System.CodeDom/CodeTypeReferenceTest.cs
mcs/class/System/Test/System.Collections.Concurrent/BlockingCollectionTests.cs [new file with mode: 0644]
mcs/class/System/Test/System.Collections.Concurrent/ChangeLog [new file with mode: 0644]
mcs/class/System/Test/System.Text.RegularExpressions/ChangeLog
mcs/class/System/Test/System.Text.RegularExpressions/RegexMatchTests.cs
mcs/class/System/Test/System.Text.RegularExpressions/RegexTrial.cs
mcs/class/corlib/ChangeLog
mcs/class/corlib/System.Collections.Concurrent/BlockingCollection.cs [deleted file]
mcs/class/corlib/System.Collections.Concurrent/ChangeLog
mcs/class/corlib/System.Collections.Concurrent/ConcurrentQueue.cs
mcs/class/corlib/System.Collections.Concurrent/IProducerConsumerCollection.cs
mcs/class/corlib/System.Collections.Concurrent/Partitioner.cs
mcs/class/corlib/System.Collections.Concurrent/Partitionners/ListPartitioner.cs
mcs/class/corlib/System.Reflection/ChangeLog
mcs/class/corlib/System.Reflection/MonoGenericClass.cs
mcs/class/corlib/System.Runtime.CompilerServices/ChangeLog
mcs/class/corlib/System.Runtime.CompilerServices/TypeForwardedFromAttribute.cs
mcs/class/corlib/System.Threading.Tasks/ChangeLog
mcs/class/corlib/System.Threading.Tasks/Future.cs
mcs/class/corlib/System.Threading.Tasks/Task.cs
mcs/class/corlib/System.Threading.Tasks/TaskFactory.cs
mcs/class/corlib/System.Threading/AggregateException.cs [deleted file]
mcs/class/corlib/System.Threading/AtomicBoolean.cs
mcs/class/corlib/System.Threading/Barrier.cs [deleted file]
mcs/class/corlib/System.Threading/CancellationToken.cs
mcs/class/corlib/System.Threading/CancellationTokenRegistration.cs
mcs/class/corlib/System.Threading/CancellationTokenSource.cs
mcs/class/corlib/System.Threading/ChangeLog
mcs/class/corlib/System.Threading/CountdownEvent.cs
mcs/class/corlib/System.Threading/ICancelableOperation.cs
mcs/class/corlib/System.Threading/Parallel.cs
mcs/class/corlib/System.Threading/ParallelLoopState.cs
mcs/class/corlib/System.Threading/SpinWait.cs
mcs/class/corlib/System.Threading/Watch.cs
mcs/class/corlib/System/Action.cs
mcs/class/corlib/System/AggregateException.cs [new file with mode: 0644]
mcs/class/corlib/System/ChangeLog
mcs/class/corlib/System/Funcs.cs
mcs/class/corlib/System/ResolveEventArgs.cs
mcs/class/corlib/System/Tuple.cs
mcs/class/corlib/System/Type.cs
mcs/class/corlib/Test/System.Collections.Concurrent/BlockingCollectionTests.cs [deleted file]
mcs/class/corlib/Test/System.Collections.Concurrent/ChangeLog
mcs/class/corlib/Test/System.Reflection/ChangeLog
mcs/class/corlib/Test/System.Reflection/MonoGenericClassTest.cs
mcs/class/corlib/Test/System.Runtime.InteropServices/ChangeLog
mcs/class/corlib/Test/System.Runtime.InteropServices/GCHandleTest.cs
mcs/class/corlib/Test/System.Threading/AggregateExceptionTests.cs [deleted file]
mcs/class/corlib/Test/System.Threading/ChangeLog
mcs/class/corlib/Test/System.Threading/ParallelTests.cs
mcs/class/corlib/Test/System/AggregateExceptionTests.cs [new file with mode: 0644]
mcs/class/corlib/corlib.dll.sources
mcs/class/corlib/corlib_test.dll.sources
mcs/errors/cs0026-3.cs [deleted file]
mcs/errors/cs0027-3.cs [new file with mode: 0644]
mcs/errors/cs0027-4.cs [new file with mode: 0644]
mcs/errors/cs0120-14.cs [new file with mode: 0644]
mcs/errors/cs0120-15.cs [new file with mode: 0644]
mcs/errors/cs0206-2.cs [new file with mode: 0644]
mcs/errors/cs0432-3.cs [new file with mode: 0644]
mcs/errors/cs0533-4.cs [new file with mode: 0644]
mcs/errors/cs0534-5.cs [deleted file]
mcs/errors/cs1967.cs [new file with mode: 0644]
mcs/mcs/ChangeLog
mcs/mcs/anonymous.cs
mcs/mcs/argument.cs
mcs/mcs/assign.cs
mcs/mcs/attribute.cs
mcs/mcs/cfold.cs
mcs/mcs/class.cs
mcs/mcs/codegen.cs
mcs/mcs/complete.cs
mcs/mcs/const.cs
mcs/mcs/constant.cs
mcs/mcs/cs-parser.jay
mcs/mcs/decl.cs
mcs/mcs/delegate.cs
mcs/mcs/dynamic.cs
mcs/mcs/ecore.cs
mcs/mcs/eval.cs
mcs/mcs/expression.cs
mcs/mcs/generic-mcs.cs
mcs/mcs/generic.cs
mcs/mcs/iterators.cs
mcs/mcs/lambda.cs
mcs/mcs/linq.cs
mcs/mcs/namespace.cs
mcs/mcs/parameter.cs
mcs/mcs/roottypes.cs
mcs/mcs/statement.cs
mcs/mcs/typemanager.cs
mcs/tests/gtest-456.cs [new file with mode: 0644]
mcs/tests/gtest-lambda-23.cs [new file with mode: 0644]
mcs/tests/gtest-partial-01.cs [new file with mode: 0644]
mcs/tests/known-issues-dmcs
mcs/tests/known-issues-gmcs
mcs/tests/known-issues-mcs
mcs/tests/ver-il-gmcs.xml
mcs/tools/mdoc/ChangeLog
mcs/tools/mdoc/Makefile
mcs/tools/mdoc/Resources/monodoc-ecma.xsd
mcs/tools/mdoc/Test/DocTest-v1.cs
mcs/tools/mdoc/Test/en.expected.importslashdoc/Mono.DocTest/DocAttribute.xml
mcs/tools/mdoc/Test/html.expected/Mono.DocTest/DocAttribute.html
mcs/tools/mdoc/Test/msxdoc-expected.importslashdoc.xml
mcs/tools/monodoc/ChangeLog
mcs/tools/monodoc/Makefile
mcs/tools/monodoc/Monodoc/provider.cs
mcs/tools/monodoc/Resources/mdoc-html-format.xsl [new file with mode: 0644]
mcs/tools/monodoc/Resources/mdoc-html-utils.xsl
mcs/tools/svcutil/ChangeLog
mcs/tools/svcutil/CommandLineOptions.cs
mcs/tools/svcutil/Driver.cs
mcs/tools/svcutil/MoonlightChannelBaseExtension.cs [new file with mode: 0644]
mcs/tools/svcutil/svcutil.exe.sources
mcs/tools/tuner/ChangeLog
mcs/tools/tuner/Mono.Tuner/InjectSecurityAttributes.cs
mcs/tools/tuner/Mono.Tuner/MoonlightA11yDescriptorGenerator.cs
mcs/tools/tuner/Mono.Tuner/MoonlightA11yProcessor.cs
mcs/tools/xbuild/ChangeLog
mcs/tools/xbuild/ErrorUtilities.cs
mcs/tools/xbuild/SolutionParser.cs
mcs/tools/xbuild/tests/ChangeLog
mcs/tools/xbuild/tests/standalone/Project01/Project01.sln.proj
mcs/tools/xbuild/xbuild/Microsoft.Common.targets
mono/arch/ChangeLog
mono/arch/arm/arm-codegen.h
mono/dis/ChangeLog
mono/dis/dis-cil.c
mono/dis/main.c
mono/io-layer/ChangeLog
mono/io-layer/processes.c
mono/io-layer/security.c
mono/io-layer/sockets.c
mono/metadata/ChangeLog
mono/metadata/Makefile.am
mono/metadata/appdomain.c
mono/metadata/boehm-gc.c
mono/metadata/cil-coff.h
mono/metadata/class-internals.h
mono/metadata/class.c
mono/metadata/class.h
mono/metadata/cominterop.c
mono/metadata/debug-helpers.c
mono/metadata/domain-internals.h
mono/metadata/domain.c
mono/metadata/exception.c
mono/metadata/gc-internal.h
mono/metadata/gc.c
mono/metadata/generic-sharing.c
mono/metadata/icall-def.h
mono/metadata/icall.c
mono/metadata/image.c
mono/metadata/loader.c
mono/metadata/marshal.c
mono/metadata/metadata-internals.h
mono/metadata/metadata-verify.c
mono/metadata/metadata.c
mono/metadata/metadata.h
mono/metadata/method-builder.c
mono/metadata/object.c
mono/metadata/profiler.c
mono/metadata/reflection.c
mono/metadata/reflection.h
mono/metadata/sgen-gc.c
mono/metadata/sgen-scan-object.h [new file with mode: 0644]
mono/metadata/threadpool.c
mono/metadata/threads.c
mono/metadata/verify.c
mono/mini/ChangeLog
mono/mini/aot-compiler.c
mono/mini/aot-runtime.c
mono/mini/debug-debugger.c
mono/mini/exceptions-alpha.c
mono/mini/exceptions-arm.c
mono/mini/exceptions-hppa.c
mono/mini/exceptions-mips.c
mono/mini/exceptions-ppc.c
mono/mini/exceptions-s390.c
mono/mini/exceptions-s390x.c
mono/mini/exceptions-sparc.c
mono/mini/exceptions-x86.c
mono/mini/method-to-ir.c
mono/mini/mini-arm.c
mono/mini/mini-exceptions.c
mono/mini/mini-trampolines.c
mono/mini/mini.c
mono/mini/mini.h
mono/mini/tramp-amd64.c
mono/mini/tramp-arm.c
mono/mini/tramp-ppc.c
mono/mini/tramp-x86.c
mono/monograph/ChangeLog
mono/monograph/monograph.c
mono/profiler/ChangeLog
mono/profiler/mono-cov.c
mono/profiler/mono-profiler-aot.c
mono/profiler/mono-profiler-logging.c
mono/tests/ChangeLog
mono/tests/Makefile.am
mono/tests/bug-528055.il [new file with mode: 0644]
mono/tests/verifier/ChangeLog
mono/tests/verifier/unverifiable_ldobj_with_generic_type_definition.il [new file with mode: 0644]
mono/tests/verifier/valid_generic_type_definition_on_boxing_position.cs [new file with mode: 0644]
mono/utils/ChangeLog
mono/utils/mono-counters.c
mono/utils/mono-hash.c
mono/utils/mono-proclib.c
mono/utils/monobitset.h
mono/utils/strtod.c
scripts/Makefile.am
winconfig.h

index 7ca04131fc3948bcf1ce548adc214d240b069c45..77b27d84b0ee0e0c7048e9390cf81ce62921d620 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2009-08-18  Zoltan Varga  <vargaz@gmail.com>
+
+       * scripts/Makefile.am: Applied patch from Hib Eris (hib@hiberis.nl).
+       Add $(SCRIPT_SUFFIX) to the name of the 'mod' tool.
+
 2009-08-04  Miguel de Icaza  <miguel@novell.com>
 
        * Start the split between PLATFORM_WIN32 and TARGET_WIN32.  
index 09f2a8259689851077b997088df268ed836055e1..d925a1e415a6ff1019647e8ad35e7ceca8d21bbe 100644 (file)
@@ -1,3 +1,8 @@
+2009-08-11 Gonzalo Paniagua Javier <gonzalo@novell.com>
+
+       * DefaultWsdlHelpGenerator.aspx: the 'Message Layout' can now handle
+       self-referencing types. Fixes bug #529353.
+
 2009-08-05  Atsushi Enomoto  <atsushi@ximian.com>
 
        * web.config: add WCF assemblies as references at compilation.
index 6d02af355e92f793da5a5d8c627f2551e6a90601..4750b01f14183e0027074ea016abe52286636197 100644 (file)
@@ -10,6 +10,7 @@
 --%>
 
 <%@ Import Namespace="System.Collections" %>
+<%@ Import Namespace="System.Collections.Generic" %>
 <%@ Import Namespace="System.IO" %>
 <%@ Import Namespace="System.Xml.Serialization" %>
 <%@ Import Namespace="System.Xml" %>
@@ -1035,7 +1036,7 @@ public class HtmlSampleGenerator: SampleGenerator
                        if (elem == null) throw new InvalidOperationException ("Element not found: " + qname);
                        WriteElementSample (xtw, qname.Namespace, elem);
                }
-               
+
                void WriteElementSample (XmlTextWriter xtw, string ns, XmlSchemaElement elem)
                {
                        bool sharedAnnType = false;
@@ -1129,9 +1130,18 @@ public class HtmlSampleGenerator: SampleGenerator
                {
                        WriteAttributes (xtw, stype.Attributes, stype.AnyAttribute);
                }
-               
+
+               Dictionary<XmlSchemaComplexType,int> recursed_types = new Dictionary<XmlSchemaComplexType,int> ();
                void WriteComplexTypeElements (XmlTextWriter xtw, string ns, XmlSchemaComplexType stype)
                {
+                       int prev = 0;
+                       if (recursed_types.ContainsKey (stype))
+                               prev = recursed_types [stype];
+
+                       if (prev > 1)
+                               return;
+                       recursed_types [stype] = ++prev;
+
                        if (stype.Particle != null)
                                WriteParticleComplexContent (xtw, ns, stype.Particle);
                        else
@@ -1141,6 +1151,8 @@ public class HtmlSampleGenerator: SampleGenerator
                                else if (stype.ContentModel is XmlSchemaComplexContent)
                                        WriteComplexContent (xtw, ns, (XmlSchemaComplexContent)stype.ContentModel);
                        }
+                       prev = recursed_types [stype];
+                       recursed_types [stype] = --prev;
                }
 
                void WriteAttributes (XmlTextWriter xtw, XmlSchemaObjectCollection atts, XmlSchemaAnyAttribute anyat)
index 546006b63bd552442fe9310f260df0483636194f..eba7c3510b2960b79454934861959b9e8069f1ed 100644 (file)
@@ -1,3 +1,7 @@
+2009-08-11  Jérémie Laval  <jeremie.laval@gmail.com>
+
+       * Consts.cs.in: Add BOOTSTRAP_NET_4_0.
+
 2009-07-18  Michael Barker  <mike@middlesoft.co.uk>
 
        * Consts.cs.in:  Added constant for Mono.Messaging.RabbitMQ.
index 29bce04c7e24d581ce01deaf0512be841ea2303b..341a4ea3f5b7c0a368c85e79421d0aec049781c2 100644 (file)
@@ -122,7 +122,7 @@ internal
        public const string AssemblySystem_ServiceProcess = "System.ServiceProcess, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";
        public const string AssemblySystem_Web = "System.Web, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";
        public const string AssemblySystem_Windows_Forms = "System.Windows.Forms, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=b77a5c561934e089";
-#if NET_4_0
+#if NET_4_0 || BOOTSTRAP_NET_4_0
        public const string AssemblySystemCore_3_5 = "System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
 #endif 
 }
index 29410a99025ba2d31e01f1dcaa58bdb02dac7536..6f7745032444f940c6c8b7acf18c88deacdc5371 100644 (file)
@@ -1,3 +1,7 @@
+2009-08-13  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * Makefile: add System.Json to net_4_0 profile.
+
 2009-07-20  Jb Evain  <jbevain@novell.com>
 
        * Makefile: set monotouch_SUBDIRS to the net_2_1 assemblies set.
index f957e1558ae9a3788e190e7f31426bf1f5ac41f3..e9d10748bb7a1c98ddb6bb6a1a6d844f323b2621 100644 (file)
@@ -158,6 +158,7 @@ net_3_5_dirs := \
 
 net_4_0_dirs := \
        System.Dynamic          \
+       System.Json             \
        Microsoft.CSharp
 
 net_1_1_bootstrap_SUBDIRS := $(bootstrap_dirs) PEAPI
index 8c52ca71dcc6c94b691e43cf345a54e651512a49..7e0e6c9d031be761faa5f7db9c05c8ae6f514813 100644 (file)
@@ -34,6 +34,7 @@ namespace System.Windows.Forms {
                private object state;
                private bool completed;
                private object return_value;
+               private Exception exception;
 
                public AsyncMethodResult ()
                {
@@ -68,10 +69,18 @@ namespace System.Windows.Forms {
                public object EndInvoke ()
                {
                        lock (this) {
-                               if (completed)
-                                       return return_value;
+                               if (completed) {
+                                       if (exception == null)
+                                               return return_value;
+                                       else
+                                               throw exception;
+                               }
                        }
                        handle.WaitOne ();
+                       
+                       if (exception != null)
+                               throw exception;
+                               
                        return return_value;
                }
 
@@ -83,6 +92,15 @@ namespace System.Windows.Forms {
                                handle.Set ();
                        }
                }
+               
+               public void CompleteWithException (Exception ex)
+               {
+                       lock (this) {
+                               completed = true;
+                               exception = ex;
+                               handle.Set ();
+                       }
+               }
        }
 
 }
index 4721c24fceef5dd3c4fd2e27a5e4bfa705f783b6..a4d5c5ee94a99038f8254e862ce6621461b5749a 100644 (file)
@@ -1,3 +1,82 @@
+2009-08-17  Carlos Alberto Cortez <calberto.cortez@gmail.com>
+
+       * ToolStripItem.cs: When the owner changes its Font, call the
+       OnFontChanged event, so we let our users know that we likely have a
+       new font - since Font is an ambient property.
+       * ToolStripDropDownItem.cs: When our Font changes, propagate that
+       information to our DropDown control, if any.
+       Fixes #531515.
+
+2009-08-17  Carlos Alberto Cortez <calberto.cortez@gmail.com>
+
+       * DataGrid.cs: 
+       * ThemeWin32Classic.cs: When the user clicks on a new cell, we should reset any
+       previous selection, just like .net does. Also, in the cases where a
+       cell is being edited and it keeps the selected status, use the normal
+       colors for it, and use the selected colors for the rest of the columns of
+       that row.
+       Fixes the remaining bits of #323051.
+
+2009-08-16  Carlos Alberto Cortez <calberto.cortez@gmail.com>
+
+       * DataGrid.cs: When getting ProcessKeyPreview fired, call Edit() if we
+       are not editing already - so the edition is actually active on our
+       column style textbox. Also, it seems the code handling process the
+       grid keys is repeated, but instead of removing it, just comment it for
+       now.
+       Fixes part of #323051.
+
+2009-08-13  Carlos Alberto Cortez <calberto.cortez@gmail.com>
+
+       * AsyncMethodResult.cs: Store a exception field in case the called
+       method actually caused an exception. This way we can throw it later.
+       * XplatUIDriver.cs: Check if the async method result has an exception
+       - throw it if needed. 
+       The idea is that Control.Invoke throws the exception from the thread
+       that called it, not the main MWF thread. 
+       Patch by Tom Spink <tspink@gmail.com>. Fixes #497175.
+
+2009-08-12  Carlos Alberto Cortez <calberto.cortez@gmail.com>
+
+       * DataGrid.cs: In mouse move we need to shift the selection in case
+       the pointer is on the row headers.
+       Fixes #323052.
+
+2009-08-11  Ivan N. Zlatev  <contact@i-nz.net>
+
+       * SplitContainer.cs: Avoid updating the splitter distance if it hasn't 
+       moved. Updating the distance was causing a re-layout which was resetting 
+       the clicks counter and preventing DoubleClick from every firing.
+       [Fixes bug #521387]
+
+2009-08-11  Carlos Alberto Cortez <calberto.cortez@gmail.com>
+
+       * DataGrid.cs: When a new TableStyle is added, don't create new
+       columns for it unless it is empty - this is the correct way to both
+       respect the columns if they were provided by our user, or create them
+       for him in case the column collection is empty.
+       Fixes #323111.
+
+2009-08-10  Carlos Alberto Cortez <calberto.cortez@gmail.com> 
+
+       * DataGrid.cs: Actually call BindColumns in the handler for
+       ListManager.MetaDataChanged, since the current code is already taking
+       into account the scenario when a custom table style is used - this was
+       confusing us before, and that's why we commented the call to
+       BindColumns. Also call CallAreasAndInvalidate, to properly reflect the
+       changes as needed.
+       Fixes #465021.
+
+2009-08-10  Carlos Alberto Cortez <calberto.cortez@gmail.com>
+
+       * DataGrid.cs: When setting the data source, if we have a user
+       provided table style available, force a complete bind in case the
+       column styles for that table style is empty.
+
+2009-08-09  Ivan N. Zlatev  <contact@i-nz.net>
+
+       * DataGridViewCell.cs: Handle null and DBNull values.
+
 2009-08-07 Rodrigo Kumpera  <rkumpera@novell.com>
 
        * ListBindingHelper.cs: Fix the 1.0 build by making this type available
index fc5b91ddbd9a44934cc26f13438914cfbead8cc2..aa6fb6fc11b989e41a1597ce38d8aec0904612e7 100644 (file)
@@ -268,7 +268,7 @@ namespace System.Windows.Forms
                /* editing state */
                bool cursor_in_add_row;
                bool add_row_changed;
-               bool is_editing;                // Current cell is edit mode
+               internal bool is_editing;               // Current cell is edit mode
                bool is_changing;
 
                internal Stack data_source_stack;
@@ -1418,20 +1418,24 @@ namespace System.Windows.Forms
                        base.OnHandleDestroyed (e);
                }
 
+               // It seems we have repeated code with ProcessKeyPreview, specifically
+               // the call to ProcessGridKey. In practice it seems this event is *never* fired
+               // since the key events are handled by the current column's textbox. 
+               // We are keeping commented anyway, in case we need to actually call it.
                protected override void OnKeyDown (KeyEventArgs ke)
                {
                        base.OnKeyDown (ke);
                        
-                       if (ProcessGridKey (ke) == true)
+                       /*if (ProcessGridKey (ke) == true)
                                ke.Handled = true;
 
-                       /* TODO: we probably don't need this check,
-                        * since current_cell wouldn't have been set
-                        * to something invalid */
+                       // TODO: we probably don't need this check,
+                       // since current_cell wouldn't have been set
+                       // to something invalid
                        if (CurrentTableStyle.GridColumnStyles.Count > 0) {
                                CurrentTableStyle.GridColumnStyles[current_cell.ColumnNumber].OnKeyDown
                                        (ke, current_cell.RowNumber, current_cell.ColumnNumber);
-                       }
+                       }*/
                }
 
                protected override void OnKeyPress (KeyPressEventArgs kpe)
@@ -1484,6 +1488,7 @@ namespace System.Windows.Forms
                                DataGridCell new_cell = new DataGridCell (testinfo.Row, testinfo.Column);
 
                                if ((new_cell.Equals (current_cell) == false) || (!is_editing)) {
+                                       ResetSelection ();
                                        CurrentCell = new_cell;
                                        Edit ();
                                } else {
@@ -1678,6 +1683,12 @@ namespace System.Windows.Forms
                                                }
                                        }
 
+                                       Cursor = Cursors.Default;
+                                       break;
+                               case HitTestType.RowHeader:
+                                       if (e.Button == MouseButtons.Left)
+                                               ShiftSelection (testinfo.Row);
+
                                        Cursor = Cursors.Default;
                                        break;
                                default:
@@ -2012,6 +2023,14 @@ namespace System.Windows.Forms
                                KeyEventArgs ke = new KeyEventArgs (key);
                                if (ProcessGridKey (ke))
                                        return true;
+
+                               // if we receive a key event, make sure that input is actually
+                               // taken into account.
+                               if (!is_editing) {
+                                       Edit ();
+                                       InvalidateRow (current_cell.RowNumber);
+                                       return true;
+                               }
                        }
 
                        return base.ProcessKeyPreview (ref m);
@@ -2449,8 +2468,10 @@ namespace System.Windows.Forms
                                } else if (CurrentTableStyle == grid_style ||
                                         CurrentTableStyle.MappingName != list_name) {
                                        // If the style has been defined by the user, use it
+                                       // Also, if the user provided style is empty,
+                                       // force a bind for it
                                        CurrentTableStyle = styles_collection[list_name];
-                                       current_style.CreateColumnsForTable (true);
+                                       current_style.CreateColumnsForTable (current_style.GridColumnStyles.Count > 0);
                                } else {
                                        current_style.CreateColumnsForTable (true);
                                }
@@ -2460,12 +2481,8 @@ namespace System.Windows.Forms
 
                private void OnListManagerMetaDataChanged (object sender, EventArgs e)
                {
-                       // XXX
-
-                       //we need to rethink this, as in 2.0 we get this event when a column is added to a table.
-                       // forcing a rebind of columns means that we fail bug #80422.  disable this for now.
-                       //
-                       // BindColumns ();
+                       BindColumns ();
+                       CalcAreasAndInvalidate ();
                }
 
                private void OnListManagerPositionChanged (object sender, EventArgs e)
@@ -2496,7 +2513,8 @@ namespace System.Windows.Forms
                        case CollectionChangeAction.Add:
                                if (e.Element != null && String.Compare (list_name, ((DataGridTableStyle)e.Element).MappingName, true) == 0) {
                                        CurrentTableStyle = (DataGridTableStyle)e.Element;
-                                       ((DataGridTableStyle) e.Element).CreateColumnsForTable (false);
+                                       // force to auto detect columns in case the new style is completely empty
+                                       ((DataGridTableStyle) e.Element).CreateColumnsForTable (CurrentTableStyle.GridColumnStyles.Count > 0);
                                }
                                break;
                        case CollectionChangeAction.Remove:
index 1aa7031cb935da594f86c2a960e9dc5908baab05..60ad73477d22a04cc6b47595c4bca00c7ae28f77 100644 (file)
@@ -887,6 +887,11 @@ namespace System.Windows.Forms {
                                value = e.Value;
                        }
                        
+                       if (value == null || (cellStyle != null && value == cellStyle.DataSourceNullValue)) {
+                               if (FormattedValueType == typeof (string))
+                                       return String.Empty;
+                       }
+
                        if (FormattedValueType == typeof(string) && value is IFormattable && !String.IsNullOrEmpty (cellStyle.Format))
                                return ((IFormattable) value).ToString (cellStyle.Format, cellStyle.FormatProvider);
                        if (value != null && FormattedValueType.IsAssignableFrom (value.GetType()))
@@ -922,7 +927,10 @@ namespace System.Windows.Forms {
                        if (DataGridView != null && (RowIndex < 0 || RowIndex >= DataGridView.Rows.Count))
                                throw new ArgumentOutOfRangeException ("rowIndex", "Specified argument was out of the range of valid values.");
                
-                       if (DataProperty != null)
+                       if (OwningRow != null && OwningRow.Index == DataGridView.NewRowIndex)
+                               return DefaultNewRowValue;
+
+                       if (DataProperty != null && OwningRow.DataBoundItem != null)
                                return DataProperty.GetValue (OwningRow.DataBoundItem);
                        
                        if (valuex != null)
index 7f44aecb7071f43ab85aedb3fbbfc51718d496db..534fc575af8ebee55c3badcb9d5565adfc62f882 100644 (file)
@@ -51,6 +51,7 @@ namespace System.Windows.Forms
                private int splitter_increment;
                private Rectangle splitter_rectangle;
                private Rectangle splitter_rectangle_moving;
+               private Rectangle splitter_rectangle_before_move;
                private bool splitter_fixed;
                private bool splitter_dragging;
                private int splitter_prev_move;
@@ -628,6 +629,7 @@ namespace System.Windows.Forms
                {
                        splitter_prev_move = orientation == Orientation.Vertical ? location.X : location.Y;
                        splitter_rectangle_moving = splitter_rectangle;
+                       splitter_rectangle_before_move = splitter_rectangle;
                }
 
                private void SplitterMove (Point location)
@@ -689,8 +691,15 @@ namespace System.Windows.Forms
                private void SplitterEndMove (Point location, bool cancel)
                {
                        if (!cancel) {
-                               splitter_rectangle = splitter_rectangle_moving;
-                               UpdateSplitter ();
+                               // Prevent updating the splitter distance if the user changes it in e.g. the
+                               // DoubleClick handler, but no delta move has happened in our drag-handling. 
+                               // We don't compare to splitter_rectangle for exactly that reason here 
+                               // (if it gets changed externally) and compare to a cached value.
+                               // 
+                               if (splitter_rectangle_before_move != splitter_rectangle_moving) {
+                                       splitter_rectangle = splitter_rectangle_moving;
+                                       UpdateSplitter ();
+                               }
                        }
                        SplitterEventArgs args = new SplitterEventArgs (location.X, location.Y, 
                                                                        splitter_rectangle.X, splitter_rectangle.Y);
index a4f14df376eb50d88572d8269996535a086ff7a1..816be0562f2709884a41022a4131a8a7dbb8f1b9 100644 (file)
@@ -2223,6 +2223,7 @@ namespace System.Windows.Forms
 
                        // PaintCells at row, column
                        int column_cnt = grid.FirstVisibleColumn + grid.VisibleColumnCount;
+                       DataGridCell current_cell = grid.CurrentCell;
 
                        if (column_cnt > 0) {
                                Region prev_clip = g.Clip;
@@ -2243,14 +2244,24 @@ namespace System.Windows.Forms
                                                current_clip.Intersect (prev_clip);
                                                g.Clip = current_clip;
 
+                                               Brush colBackBrush = backBrush;
+                                               Brush colForeBrush = foreBrush;
+
+                                               // If we are in the precise cell we are editing, then use the normal colors
+                                               // even if we are selected.
+                                               if (grid.is_editing && column == current_cell.ColumnNumber && row == current_cell.RowNumber) {
+                                                       colBackBrush = ResPool.GetSolidBrush (grid.BackColor);
+                                                       colForeBrush = ResPool.GetSolidBrush (grid.ForeColor);
+                                               }
+
                                                if (is_newrow) {
                                                        grid.CurrentTableStyle.GridColumnStyles[column].PaintNewRow (g, rect_cell, 
-                                                                                                                    backBrush,
-                                                                                                                    foreBrush);
+                                                                                                                    colBackBrush,
+                                                                                                                    colForeBrush);
                                                } else {
                                                        grid.CurrentTableStyle.GridColumnStyles[column].Paint (g, rect_cell, grid.ListManager, row,
-                                                                                                              backBrush,
-                                                                                                              foreBrush,
+                                                                                                              colBackBrush,
+                                                                                                              colForeBrush,
                                                                                                               grid.RightToLeft == RightToLeft.Yes);
                                                }
 
index 985816a298234d947b3e3b8f502042341fdf4e8c..5465739ab1ecb14dc7965b857f5814bb701b1b69 100644 (file)
@@ -226,6 +226,11 @@ namespace System.Windows.Forms
                protected override void OnFontChanged (EventArgs e)
                {
                        base.OnFontChanged (e);
+
+                       // don't use DropDown directly, since doing that
+                       // would created the DropDown control
+                       if (drop_down != null)
+                               drop_down.Font = Font;
                }
 
                protected override void OnRightToLeftChanged (EventArgs e)
index 0eac97fe367aa528577b2afe9f6d5c8066dbf42a..9ccbff040017da4677c19f249113d7748b754cb7 100644 (file)
@@ -1176,6 +1176,7 @@ namespace System.Windows.Forms
                protected internal virtual void OnOwnerFontChanged (EventArgs e)
                {
                        this.CalculateAutoSize ();
+                       OnFontChanged (EventArgs.Empty);
                }
                
                protected virtual void OnPaint (PaintEventArgs e)
index 93bc594745d95c1eabd15bed34f46bcc75ba0c65..bf8efc08f3b02bb12ed4e8d5264200de213d2ea2 100644 (file)
@@ -476,7 +476,19 @@ namespace System.Windows.Forms {
                {
                        AsyncMethodData data = (AsyncMethodData) state;
                        AsyncMethodResult result = data.Result;
-                       object ret = data.Method.DynamicInvoke (data.Args);
+                       
+                       object ret;
+                       try {
+                               ret = data.Method.DynamicInvoke (data.Args);
+                       } catch (Exception ex) {
+                               if (result != null) {
+                                       result.CompleteWithException (ex);
+                                       return;
+                               }
+                               
+                               throw;
+                       }
+               
                        if (result != null) {
                                result.Complete (ret);
                        }
@@ -511,12 +523,16 @@ namespace System.Windows.Forms {
                        }
 #endif
 
+                       AsyncMethodResult result = data.Result;
+                       object ret;
+
                        try {
-                               AsyncMethodResult result = data.Result;
-                               object ret = data.Method.DynamicInvoke (data.Args);
+                               ret = data.Method.DynamicInvoke (data.Args);
                                result.Complete (ret);
-                       }
-                       finally {
+                       } catch (Exception ex) {
+                               result.CompleteWithException (ex);
+                               return;
+                       } finally {
 #if !MWF_ON_MSRUNTIME
                                if (data.Stack != null) {
                                        // whatever occurs we must revert to the original compressed
index 9ac5c25544bf6548850b183076668399461b33e8..00865031f1be65aa3ca8a80ec54d28f862752865 100644 (file)
@@ -1,3 +1,13 @@
+2009-08-10  Carlos Alberto Cortez <calberto.cortez@gmail.com>
+
+       * DataGridTest.cs: Don't use DataGrid.Rows.Add() for our latest test,
+       since it is 2.0. Use DataGrid.NewRow() instead.
+
+2009-08-10  Carlos Alberto Cortez <calberto.cortez@gmail.com>
+
+       * DataGridTest.cs: New test for the interaction between DataSource and
+       TableStyles.
+
 2009-08-03  Carlos Alberto Cortez <calberto.cortez@gmail.com>
 
        * GridColumnStylesCollectionTest.cs: New test for #465019. Also make
index eb9ad4f594f7bb63255e167e6cfa85da742a7134..f49ecd88cdc6f4715a06dcdb7fa1d2da68c3daeb 100644 (file)
@@ -594,5 +594,30 @@ namespace MonoTests.System.Windows.Forms
                        dg.DataSource = ds;
                        Assert.AreEqual (0, data_source_changed_count, "A3");
                }
+
+               [Test]
+               public void TestManagerSetDataSourceWithEmptyStyle ()
+               {
+                       TestDataGrid dg = new TestDataGrid ();
+                       dg.BindingContext = new BindingContext ();
+
+                       DataSet ds = new DataSet ("DataSet");
+                       DataTable dt = new DataTable ("MyTable");
+                       dt.Columns.Add ("A", typeof (string));
+                       dt.NewRow ();
+                       ds.Tables.Add (dt);
+
+                       // Add the style for the table we have, but leave it empty
+                       // - this is, no column styles
+                       DataGridTableStyle table_style = new DataGridTableStyle ();
+                       table_style.MappingName = "MyTable";
+                       dg.TableStyles.Add (table_style);
+
+                       Assert.AreEqual (0, table_style.GridColumnStyles.Count, "#A1");
+
+                       dg.DataSource = dt;
+
+                       Assert.AreEqual (1, table_style.GridColumnStyles.Count, "#B1");
+               }
        }
 }
index 293c524fbf7732e1fb3bc1c0c3a61634402a408f..a5405eb603f73f0a55deca9fcccdb26aea8aa3d8 100644 (file)
@@ -62,7 +62,7 @@ namespace Microsoft.Build.BuildEngine {
                protected void Init ()
                {
                        // all referenced item lists
-                       consumedItemsByName = new Dictionary<string, BuildItemGroup> ();
+                       consumedItemsByName = new Dictionary<string, BuildItemGroup> (StringComparer.InvariantCultureIgnoreCase);
 
                        // all referenced metadata
                        consumedMetadataReferences = new List<MetadataReference> ();
@@ -72,10 +72,10 @@ namespace Microsoft.Build.BuildEngine {
 
                protected void BatchAndPrepareBuckets ()
                {
-                       batchedItemsByName = new Dictionary<string, BuildItemGroup> ();
+                       batchedItemsByName = new Dictionary<string, BuildItemGroup> (StringComparer.InvariantCultureIgnoreCase);
 
                        // These will passed as is for every batch
-                       commonItemsByName = new Dictionary<string, BuildItemGroup> ();
+                       commonItemsByName = new Dictionary<string, BuildItemGroup> (StringComparer.InvariantCultureIgnoreCase);
 
                        ValidateUnqualifiedMetadataReferences ();
 
@@ -158,8 +158,8 @@ namespace Microsoft.Build.BuildEngine {
 
                ICollection<Dictionary<string, BuildItemGroup>> Bucketize ()
                {
-                       Dictionary<string, Dictionary<string, BuildItemGroup>> buckets =
-                               new Dictionary<string, Dictionary<string, BuildItemGroup>> ();
+                       var buckets = new Dictionary<string, Dictionary<string, BuildItemGroup>> (
+                                       StringComparer.InvariantCultureIgnoreCase);
 
                        // For each item list represented in "BatchedItemNames", and then for each item
                        // within that list, get the values for that item for each of the metadata in
@@ -198,7 +198,8 @@ namespace Microsoft.Build.BuildEngine {
                                        Dictionary<string, BuildItemGroup> bucket;
                                        if (!buckets.TryGetValue (bucket_key, out bucket))
                                                // new bucket
-                                               buckets [bucket_key] = bucket = new Dictionary<string, BuildItemGroup> ();
+                                               buckets [bucket_key] = bucket = new Dictionary<string, BuildItemGroup> (
+                                                               StringComparer.InvariantCultureIgnoreCase);
 
                                        string itemGroup_key = item.Name;
                                        BuildItemGroup itemGroup;
index 476085ab2b3cb0ae96b2adbd0dbfad762a947f1b..fcc8c943a21ce65c749c53de6c2655d68c6152ee 100644 (file)
@@ -1,3 +1,17 @@
+2009-08-18  Ankit Jain  <jankit@novell.com>
+
+       * BatchingImplBase.cs: Make the item name lookups and metadata be case
+       insensitive.
+       * TaskDatabase.cs: Likewise.
+       * TaskEngine.cs: Make property name looks, case insensitive.
+
+2009-08-09  Miguel de Icaza  <miguel@novell.com>
+
+       * ConsoleLogger.cs: Change the format of the error and warnings
+       strings to work when invoked inside Emacs by not rendering the
+       column if available, by using lowercase "error"/"warning" strings
+       instead of camelcased versions and to not have unnecessary padding.
+
 2009-07-31  Ankit Jain  <jankit@novell.com>
 
        * ConsoleLogger.cs: Keep track of all the errors and warnings
index d1919c0c72e8f5061e246e254d595e1f7b2595a3..52740db4423945c07a63d99ca265d984883be8d8 100644 (file)
@@ -261,27 +261,49 @@ namespace Microsoft.Build.BuildEngine {
                public virtual void Shutdown ()
                {
                }
+
+               static bool InEmacs = Environment.GetEnvironmentVariable ("EMACS") == "t";
                
                private string FormatErrorEvent (BuildErrorEventArgs args)
                {
-                       // FIXME: show more complicated args
-                       if (args.LineNumber != 0 && args.ColumnNumber != 0) {
-                               return String.Format ("{0}({1},{2}): {3} Error {4}: {5}", args.File, args.LineNumber, args.ColumnNumber,
-                                       args.Subcategory, args.Code, args.Message);
+                       // For some reason we get an 1-char empty string as Subcategory somtimes.
+                       string subprefix = args.Subcategory == null || args.Subcategory == "" || args.Subcategory == " " ? "" : " ";
+                       string subcat = subprefix == "" ? "" : args.Subcategory;
+                               
+                       if (args.LineNumber != 0){
+                               if (args.ColumnNumber != 0 && !InEmacs) 
+                                       return String.Format ("{0}({1},{2}): {3}{4}error {5}: {6}",
+                                                             args.File, args.LineNumber, args.ColumnNumber,
+                                                             subprefix, subcat, args.Code, args.Message);
+
+                               return String.Format ("{0}({1}): {2}{3}error {4}: {5}",
+                                                     args.File, args.LineNumber,
+                                                     subprefix, subcat, args.Code, args.Message);
                        } else {
-                               return String.Format ("{0}: {1} Error {2}: {3}", args.File, args.Subcategory, args.Code,
+                               return String.Format ("{0}: {1}{2}error {3}: {4}", args.File, subprefix, subcat, args.Code,
                                        args.Message);
                        }
                }
 
                private string FormatWarningEvent (BuildWarningEventArgs args)
                {
+                       // For some reason we get an 1-char empty string as Subcategory somtimes.
+                       string subprefix = args.Subcategory == null || args.Subcategory == "" || args.Subcategory == " " ? "" : " ";
+                       string subcat = subprefix == "" ? "" : args.Subcategory;
+
                        // FIXME: show more complicated args
-                       if (args.LineNumber != 0 && args.ColumnNumber != 0) {
-                               return String.Format ("{0}({1},{2}): {3} Warning {4}: {5}", args.File, args.LineNumber, args.ColumnNumber,
-                                       args.Subcategory, args.Code, args.Message);
+                       if (args.LineNumber != 0){
+
+                               if (args.ColumnNumber != 0 && !InEmacs) {
+                                       return String.Format ("{0}({1},{2}): {3}{4}warning {5}: {6}",
+                                                             args.File, args.LineNumber, args.ColumnNumber,
+                                                             subprefix, subcat, args.Code, args.Message);
+                               }
+                               return String.Format ("{0}({1}): {2}{3}warning {4}: {5}",
+                                                     args.File, args.LineNumber,
+                                                     subprefix, subcat, args.Code, args.Message);
                        } else {
-                               return String.Format ("{0}: {1} Warning {2}: {3}", args.File, args.Subcategory, args.Code,
+                               return String.Format ("{0}: {1} warning {2}: {3}", args.File, args.Subcategory, args.Code,
                                        args.Message);
                        }
                }
index 33c2add942390a3339910bf97cd37328b3f98f57..f40f4f94b8bd923a2a491400811bd4fb604b9517 100644 (file)
@@ -47,9 +47,9 @@ namespace Microsoft.Build.BuildEngine {
                public TaskDatabase ()
                {
                        assemblyInformation = new Dictionary <string, AssemblyLoadInfo> ();
-                       typesByFullName = new Dictionary <string, Type> ();
-                       typesByShortName = new Dictionary <string, Type> ();
-                       usingTasksByFullName = new Dictionary <string, UsingTaskInfo> ();
+                       typesByFullName = new Dictionary <string, Type> (StringComparer.InvariantCultureIgnoreCase);
+                       typesByShortName = new Dictionary <string, Type> (StringComparer.InvariantCultureIgnoreCase);
+                       usingTasksByFullName = new Dictionary <string, UsingTaskInfo> (StringComparer.InvariantCultureIgnoreCase);
                }
                
                public void RegisterTask (string classname, AssemblyLoadInfo assemblyLoadInfo)
@@ -94,7 +94,7 @@ namespace Microsoft.Build.BuildEngine {
                                if (is_shortname) {
                                        // Linear search UsingTaskInfo objects for short name match
                                        foreach (UsingTaskInfo ut_info in usingTasksByFullName.Values) {
-                                               if (String.Compare (ut_info.ShortName, classname) == 0) {
+                                               if (String.Compare (ut_info.ShortName, classname, true) == 0) {
                                                        info = ut_info;
                                                        break;
                                                }
index 62fbb099fe46daae6665d2a4cefbc3251999571a..569e1e30c7555eb204288a8b3d22e37f3749c7aa 100644 (file)
@@ -68,10 +68,11 @@ namespace Microsoft.Build.BuildEngine {
                        this.task = task;
                        this.taskElement = taskElement;
                        this.taskType = taskType;
-                       values = new Dictionary <string, object> ();
+                       values = new Dictionary <string, object> (StringComparer.InvariantCultureIgnoreCase);
                        
                        foreach (KeyValuePair <string, string> de in parameters) {
-                               currentProperty = taskType.GetProperty (de.Key);
+                               currentProperty = taskType.GetProperty (de.Key, BindingFlags.Public | BindingFlags.Instance
+                                               | BindingFlags.IgnoreCase);
                                if (currentProperty == null)
                                        throw new InvalidProjectFileException (String.Format ("Task does not have property \"{0}\" defined",
                                                de.Key));
@@ -129,7 +130,8 @@ namespace Microsoft.Build.BuildEngine {
                                itemName = xmlElement.GetAttribute ("ItemName");
                                propertyName = xmlElement.GetAttribute ("PropertyName");
                                
-                               propertyInfo = taskType.GetProperty (taskParameter);
+                               propertyInfo = taskType.GetProperty (taskParameter, BindingFlags.Public | BindingFlags.Instance |
+                                                       BindingFlags.IgnoreCase);
                                if (propertyInfo == null)
                                        throw new Exception (String.Format (
                                                "The parameter '{0}' was not found for the '{1}' task.", taskParameter, taskElement.Name));
index 2ff7f2cae5449a8c83f2f17fb42f01cbd5574697..e80067631e1b0c2b1f1474a1657b2a08ec92a1f4 100644 (file)
@@ -1,3 +1,7 @@
+2009-08-18  Ankit Jain  <jankit@novell.com>
+
+       * ProjectTest.cs (TestCaseSensitivityOfProjectElements): New.
+
 2009-07-30  Ankit Jain  <jankit@novell.com>
 
        * EngineTest.cs (TestNewProject): Disable. Invalid for
index b84cff7077df169bb785a86149a6ca898c4c03ec..106637267c82d902fefbf537f8d15a39f5196af5 100644 (file)
@@ -1581,6 +1581,68 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
                        Assert.AreEqual ("count: 0", group [0].FinalItemSpec, "A3");
                }
 
+               [Test]
+               public void TestCaseSensitivityOfProjectElements ()
+               {
+                       string projectXml = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" ToolsVersion=""3.5"">
+        <ItemGroup>
+                <Abc Include=""foo"">
+                        <MetaDaTA1>md1</MetaDaTA1>
+                        <METadata2>md2</METadata2>
+                </Abc>
+                <Abc Include=""FOO"">
+                        <MetaDaTA1>MD1 caps</MetaDaTA1>
+                        <METadata2>MD2 caps</METadata2>
+                </Abc>
+                <Abc Include=""hmm"">
+                        <MetaDaTA1>Md1 CAPS</MetaDaTA1>
+                        <METadata2>MD2 CAPS</METadata2>
+                </Abc>
+                <Abc Include=""bar"">
+                        <MeTAdata1>md3</MeTAdata1>
+                        <Metadata2>md4</Metadata2>
+                </Abc>
+        </ItemGroup> 
+        <PropertyGroup><ProP1>ValueProp</ProP1></PropertyGroup>
+       <Target Name=""Main"">
+               <MesSAGE Text=""Full item: @(ABC)""/>
+               <MEssaGE Text=""metadata1 :%(AbC.MetaDATA1) metadata2: %(ABC.MetaDaTa2)""/>
+               <MEssaGE Text=""metadata2 : %(AbC.MetaDAta2)""/>
+               <MEssaGE Text=""Abc identity: %(ABC.IDENTitY)""/>
+               <MEssaGE Text=""prop1 : $(pROp1)""/>
+       </Target>
+</Project>
+";
+                       Engine engine = new Engine (Consts.BinPath);
+                       Project project = engine.CreateNewProject ();
+                       MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
+                               new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
+                       engine.RegisterLogger (logger);
+
+                       project.LoadXml (projectXml);
+                       bool result = project.Build ("Main");
+                       if (!result) {
+                               logger.DumpMessages ();
+                               Assert.Fail ("A1: Build failed");
+                       }
+                       logger.DumpMessages ();
+
+                       logger.CheckLoggedMessageHead ("Full item: foo;FOO;hmm;bar", "#A2");
+                       logger.CheckLoggedMessageHead ("metadata1 :md1 metadata2: md2", "#A3");
+                       logger.CheckLoggedMessageHead ("metadata1 :MD1 caps metadata2: MD2 caps", "#A4");
+                       logger.CheckLoggedMessageHead ("metadata1 :md3 metadata2: md4", "#A5");
+                       logger.CheckLoggedMessageHead ("metadata2 : md2", "#A6");
+                       logger.CheckLoggedMessageHead ("metadata2 : MD2 caps", "#A7");
+                       logger.CheckLoggedMessageHead ("metadata2 : md4", "#A8");
+                       logger.CheckLoggedMessageHead ("Abc identity: foo", "#A9");
+                       logger.CheckLoggedMessageHead ("Abc identity: hmm", "#A10");
+                       logger.CheckLoggedMessageHead ("Abc identity: bar", "#A11");
+                       logger.CheckLoggedMessageHead ("prop1 : ValueProp", "#A12");
+
+                       Assert.AreEqual (0, logger.NormalMessageCount, "Unexpected extra messages found");
+
+               }
+
                // full solution test
                //[Test]
                public void TestBuildSolutionProject ()
index f52cdcb0b53e9c831d575e87655febfd2ef138d8..d49decbc67b7661beed64f024237b5c98c291891 100644 (file)
@@ -1,3 +1,8 @@
+2009-08-14  Ankit Jain  <jankit@novell.com>
+
+       * Microsoft.Build.Tasks_test.dll.sources: Added
+       PcFileCache.cs from md.
+
 2009-07-23  Ankit Jain  <jankit@novell.com>
 
        * Microsoft.Build.Tasks_test.dll.sources: Added
index 904e29baf9c0452cc8ac003e573ab70a8c0d6e50..3fcfd02c95f9ca758d4b88c688c039bdfce74ba2 100644 (file)
@@ -84,6 +84,7 @@ Microsoft.Build.Tasks/MakeDir.cs
 Microsoft.Build.Tasks/ManagedCompiler.cs
 Microsoft.Build.Tasks/Message.cs
 Microsoft.Build.Tasks/MSBuild.cs
+Microsoft.Build.Tasks/PcFileCache.cs
 Microsoft.Build.Tasks/ReadLinesFromFile.cs
 Microsoft.Build.Tasks/RegisterAssembly.cs
 Microsoft.Build.Tasks/RemoveDir.cs
index 72e1c1b786b93381876d9b0f3abe4076a197efa9..a3ebe27d1bed14425196f3fbc925feb521290864 100644 (file)
 using System;
 using System.Collections.Generic;
 using System.IO;
+using System.Linq;
 using System.Reflection;
 using System.Security;
 using Microsoft.Build.Framework;
 using Microsoft.Build.Utilities;
+using Mono.PkgConfig;
 
 namespace Microsoft.Build.Tasks {
        internal class AssemblyResolver {
@@ -46,6 +48,8 @@ namespace Microsoft.Build.Tasks {
                TaskLoggingHelper log;
                StringWriter sw;
 
+               static PcFileCache cache;
+
                public AssemblyResolver ()
                {
                        gac = new Dictionary<string, Dictionary<Version, string>> ();
@@ -123,7 +127,7 @@ namespace Microsoft.Build.Tasks {
 
                        KeyValuePair<AssemblyName, string> pair;
                        if (gac_asm.NameToAssemblyNameCache.TryGetValue (key_aname.Name, out pair)) {
-                               if (AssemblyNamesCompatible (key_aname, pair.Key, specific_version)) {
+                               if (AssemblyNamesCompatible (key_aname, pair.Key, specific_version, true)) {
                                        // gac and tgt frmwk refs are not copied private
                                        return GetResolvedReference (reference, pair.Value, pair.Key, false,
                                                        SearchPath.TargetFrameworkDirectory);
@@ -221,6 +225,34 @@ namespace Microsoft.Build.Tasks {
                        return GetResolvedReference (reference, gac [name.Name] [highest], name, false, SearchPath.Gac);
                }
 
+               public ResolvedReference ResolvePkgConfigReference (ITaskItem reference, bool specific_version)
+               {
+                       PackageAssemblyInfo pkg = null;
+
+                       if (specific_version) {
+                               pkg = PcCache.GetAssemblyLocation (reference.ItemSpec);
+                       } else {
+                               // if not specific version, then just match simple name
+                               string name = reference.ItemSpec;
+                               if (name.IndexOf (',') > 0)
+                                       name = name.Substring (0, name.IndexOf (','));
+                               pkg = PcCache.ResolveAssemblyName (name).FirstOrDefault ();
+                       }
+
+                       if (pkg == null) {
+                               SearchLogger.WriteLine ("Considered {0}, but could not find in any pkg-config files.",
+                                               reference.ItemSpec);
+                               return null;
+                       }
+
+                       ResolvedReference rr = GetResolvedReference (reference, pkg.File, new AssemblyName (pkg.FullName),
+                                               false, SearchPath.PkgConfig);
+                       rr.FoundInSearchPathAsString = String.Format ("{{PkgConfig}} provided by package named {0}",
+                                                       pkg.ParentPackage.Name);
+
+                       return rr;
+               }
+
                public ResolvedReference ResolveHintPathReference (ITaskItem reference, bool specific_version)
                {
                        AssemblyName name = new AssemblyName (reference.ItemSpec);
@@ -274,32 +306,41 @@ namespace Microsoft.Build.Tasks {
 
                internal static bool AssemblyNamesCompatible (AssemblyName a, AssemblyName b, bool specificVersion)
                {
-                       if (a.Name != b.Name)
+                       return AssemblyNamesCompatible (a, b, specificVersion, false);
+               }
+
+               // if @specificVersion is true then match full name, else just the simple name
+               internal static bool AssemblyNamesCompatible (AssemblyName a, AssemblyName b, bool specificVersion,
+                               bool ignoreCase)
+               {
+                       if (String.Compare (a.Name, b.Name, ignoreCase) != 0)
                                return false;
 
+                       if (!specificVersion)
+                               // ..and simple names match
+                               return true;
+
                        if (a.CultureInfo != null && !a.CultureInfo.Equals (b.CultureInfo))
                                return false;
 
-                       if (specificVersion && a.Version != null && a.Version != b.Version)
+                       if (a.Version != null && a.Version != b.Version)
                                return false;
 
                        byte [] a_bytes = a.GetPublicKeyToken ();
                        byte [] b_bytes = b.GetPublicKeyToken ();
 
-                       if (specificVersion) {
-                               bool a_is_empty = (a_bytes == null || a_bytes.Length == 0);
-                               bool b_is_empty = (b_bytes == null || b_bytes.Length == 0);
+                       bool a_is_empty = (a_bytes == null || a_bytes.Length == 0);
+                       bool b_is_empty = (b_bytes == null || b_bytes.Length == 0);
 
-                               if (a_is_empty && b_is_empty)
-                                       return true;
+                       if (a_is_empty && b_is_empty)
+                               return true;
 
-                               if (a_is_empty || b_is_empty)
-                                       return false;
+                       if (a_is_empty || b_is_empty)
+                               return false;
 
-                               for (int i = 0; i < a_bytes.Length; i++)
-                                       if (a_bytes [i] != b_bytes [i])
-                                               return false;
-                       }
+                       for (int i = 0; i < a_bytes.Length; i++)
+                               if (a_bytes [i] != b_bytes [i])
+                                       return false;
 
                        return true;
                }
@@ -313,14 +354,14 @@ namespace Microsoft.Build.Tasks {
 
                // FIXME: to get default values of CopyLocal, compare with TargetFrameworkDirectories
 
-               // If metadata 'Private' is present then use that or use @default_value
+               // If metadata 'Private' is present then use that or use @default_copy_local_value
                // as the value for CopyLocal
                internal ResolvedReference GetResolvedReference (ITaskItem reference, string filename,
-                               AssemblyName aname, bool default_value, SearchPath search_path)
+                               AssemblyName aname, bool default_copy_local_value, SearchPath search_path)
                {
                        string pvt = reference.GetMetadata ("Private");
 
-                       bool copy_local = default_value;
+                       bool copy_local = default_copy_local_value;
                        if (!String.IsNullOrEmpty (pvt))
                                //FIXME: log a warning for invalid value
                                Boolean.TryParse (pvt, out copy_local);
@@ -331,7 +372,22 @@ namespace Microsoft.Build.Tasks {
                }
 
                public TaskLoggingHelper Log {
-                       set { log = value; }
+                       set {
+                               log = value;
+                               PcFileCacheContext.Log = value;
+                       }
+               }
+
+               static PcFileCache PcCache  {
+                       get {
+                               if (cache == null) {
+                                       PcFileCacheContext context = new PcFileCacheContext ();
+                                       cache = new PcFileCache (context);
+                                       cache.Update ();
+                               }
+
+                               return cache;
+                       }
                }
        }
 
@@ -344,7 +400,33 @@ namespace Microsoft.Build.Tasks {
                public TargetFrameworkAssemblies (string path)
                {
                        this.Path = path;
-                       NameToAssemblyNameCache = new Dictionary<string, KeyValuePair<AssemblyName, string>> ();
+                       NameToAssemblyNameCache = new Dictionary<string, KeyValuePair<AssemblyName, string>> (
+                                       StringComparer.InvariantCultureIgnoreCase);
+               }
+       }
+
+       class PcFileCacheContext : IPcFileCacheContext
+       {
+               public static TaskLoggingHelper Log;
+
+               // In the implementation of this method, the host application can extract
+               // information from the pc file and store it in the PackageInfo object
+               public void StoreCustomData (PcFile pcfile, PackageInfo pkg)
+               {
+               }
+
+               // Should return false if the provided package does not have required
+               // custom data
+               public bool IsCustomDataComplete (string pcfile, PackageInfo pkg)
+               {
+                       return true;
+               }
+
+               // Called to report errors
+               public void ReportError (string message, Exception ex)
+               {
+                       Log.LogMessage (MessageImportance.Low, "Error loading pkg-config files: {0} : {1}",
+                                       message, ex.ToString ());
                }
        }
 
@@ -355,7 +437,8 @@ namespace Microsoft.Build.Tasks {
                CandidateAssemblies,
                HintPath,
                Directory,
-               RawFileName
+               RawFileName,
+               PkgConfig
        }
 }
 
index bd19aed0891a187c93337bb1b1e6db62ce0f0e50..73f192ab995706073812074406a89f573da7bbb2 100644 (file)
@@ -1,3 +1,40 @@
+2009-08-18  Ankit Jain  <jankit@novell.com>
+
+       * TaskLoggingHelperExtensios.cs (.ctor): Mark internal.
+
+2009-08-18  Ankit Jain  <jankit@novell.com>
+
+       * PcFileCache.cs (PackageInfo): Mark internal.
+
+2009-08-18  Ankit Jain  <jankit@novell.com>
+
+       * AssemblyResolver.cs (FindInTargetFramework): Perform case insensitive
+       assembly name comparison. Use the new AssemblyNamesCompatible api.
+       (AssemblyNamesCompatible): Add new overload with a 'ignoreCase' param.
+
+2009-08-17  Ankit Jain  <jankit@novell.com>
+
+       * AssemblyResolver.cs (TargetFrameworkAssemblies..ctor): Make assembly
+       name lookups for target framework assemblies, case insensitive. Helps
+       with cases like "System.configuration", which vs.net is known to emit.
+
+2009-08-14  Ankit Jain  <jankit@novell.com>
+
+       * PcFileCache.cs: New. From monodevelop.
+       * AssemblyResolver.cs (ResolvePkgConfigReference): New. Use PcFileCache
+       to resolve assembly references.
+       (AssemblyNamesCompatible): If SpecificVersion is false, then compare
+       only simple names.
+       (GetResolvedReference): Rename default_value to default_copy_local_value.
+       (Cache): New.
+       (PcFileCacheContext): New.
+       (SearchPath): Add 'PkgConfig' to the enum.
+       * ResolveAssemblyReference.cs: Add support for '{PkgConfig}'. Update
+       messages.
+       * ResolvedReference.cs (FoundInSearchPathToString): Create from ..
+       (FoundInSearchPathAsString): .. this. Change this to a property to
+       allow custom "found in .. " messages.
+
 2009-07-31  Ankit Jain  <jankit@novell.com>
 
        * MSBuild.cs (Execute): Log error if the file doesn't exist.
diff --git a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/PcFileCache.cs b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/PcFileCache.cs
new file mode 100644 (file)
index 0000000..63cda26
--- /dev/null
@@ -0,0 +1,707 @@
+// 
+// PcFileCache.cs
+//  
+// Author:
+//       Lluis Sanchez Gual <lluis@novell.com>
+// 
+// Copyright (c) 2009 Novell, Inc (http://www.novell.com)
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+// 
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using System;
+using System.Text;
+using System.Xml;
+using System.IO;
+using System.Collections.Generic;
+
+namespace Mono.PkgConfig
+{
+       internal interface IPcFileCacheContext
+       {
+               // In the implementation of this method, the host application can extract
+               // information from the pc file and store it in the PackageInfo object
+               void StoreCustomData (PcFile pcfile, PackageInfo pkg);
+               
+               // Should return false if the provided package does not have required
+               // custom data
+               bool IsCustomDataComplete (string pcfile, PackageInfo pkg);
+               
+               // Called to report errors
+               void ReportError (string message, Exception ex);
+       }
+       
+       internal class PcFileCache
+       {
+               const string CACHE_VERSION = "2";
+               
+               Dictionary<string, PackageInfo> infos = new Dictionary<string, PackageInfo> ();
+               Dictionary<string, PackageAssemblyInfo> assemblyLocations;
+               string cacheFile;
+               bool hasChanges;
+               IPcFileCacheContext ctx;
+               
+               public PcFileCache (IPcFileCacheContext ctx)
+               {
+                       this.ctx = ctx;
+                       try {
+                               string path = Environment.GetFolderPath (Environment.SpecialFolder.ApplicationData);
+                               path = Path.Combine (path, "xbuild");
+                               if (!Directory.Exists (path))
+                                       Directory.CreateDirectory (path);
+                               cacheFile = Path.Combine (path, "pkgconfig-cache-" + CACHE_VERSION + ".xml");
+                               
+                               if (File.Exists (cacheFile))
+                                       Load ();
+                               
+                       } catch (Exception ex) {
+                               ctx.ReportError ("pc file cache could not be loaded.", ex);
+                       }
+               }
+               
+               // Updates the pkg-config index, using the default search directories
+               public void Update ()
+               {
+                       string pkgConfigPath = Environment.GetEnvironmentVariable ("PKG_CONFIG_PATH");
+                       string pkgConfigDir = Environment.GetEnvironmentVariable ("PKG_CONFIG_LIBDIR");
+                       Update (GetPkgconfigPaths (null, pkgConfigPath, pkgConfigDir));
+               }
+
+               // Updates the pkg-config index, looking for .pc files in the provided directories
+               public void Update (IEnumerable<string> pkgConfigDirs)
+               {
+                       foreach (string pcdir in pkgConfigDirs) {
+                               foreach (string pcfile in Directory.GetFiles (pcdir, "*.pc"))
+                                       GetPackageInfo (pcfile);
+                       }
+                       Save ();
+               }
+               
+               // Returns the location of an assembly, given the full name
+               public PackageAssemblyInfo GetAssemblyLocation (string fullName)
+               {
+                       lock (infos) {
+                               if (assemblyLocations == null) {
+                                       // Populate on demand
+                                       assemblyLocations = new Dictionary<string, PackageAssemblyInfo> ();
+                                       foreach (PackageInfo info in infos.Values) {
+                                               if (info.IsValidPackage) {
+                                                       foreach (PackageAssemblyInfo asm in info.Assemblies)
+                                                               assemblyLocations [NormalizeAsmName (asm.FullName)] = asm;
+                                               }
+                                       }
+                               }
+                       }
+                       // This collection is read-only once built, so there is no need for a lock
+                       PackageAssemblyInfo pasm;
+                       assemblyLocations.TryGetValue (NormalizeAsmName (fullName), out pasm);
+                       return pasm;
+               }
+               
+               public IEnumerable<PackageAssemblyInfo> ResolveAssemblyName (string name)
+               {
+                       foreach (PackageInfo pinfo in infos.Values) {
+                               if (pinfo.IsValidPackage) {
+                                       foreach (PackageAssemblyInfo asm in pinfo.Assemblies) {
+                                               if (asm.Name == name)
+                                                       yield return asm;
+                                       }
+                               }
+                       }
+               }
+               
+               // Returns information about a .pc file
+               public PackageInfo GetPackageInfo (string file)
+               {
+                       PackageInfo info;
+                       file = Path.GetFullPath (file);
+                       
+                       DateTime wtime = File.GetLastWriteTime (file);
+                       
+                       lock (infos) {
+                               if (infos.TryGetValue (file, out info)) {
+                                       if (info.LastWriteTime == wtime)
+                                               return info;
+                               }
+                       }
+
+                       try {
+                               info = ParsePackageInfo (file);
+                       } catch (Exception ex) {
+                               ctx.ReportError ("Error while parsing .pc file", ex);
+                               info = new PackageInfo ();
+                       }
+                       
+                       lock (infos) {
+                               if (!info.IsValidPackage)
+                                       info = new PackageInfo (); // Create a default empty instance
+                               info.LastWriteTime = wtime;
+                               infos [file] = info;
+                               hasChanges = true;
+                       }
+                       
+                       return info;
+               }
+               
+               FileStream OpenFile (FileAccess access)
+               {
+                       int retries = 6;
+                       FileMode mode = access == FileAccess.Read ? FileMode.Open : FileMode.Create;
+                       Exception lastException = null;
+                       
+                       while (retries > 0) {
+                               try {
+                                       return new FileStream (cacheFile, mode, access, FileShare.None);
+                               } catch (Exception ex) {
+                                       // the file may be locked by another app. Wait a bit and try again
+                                       lastException = ex;
+                                       System.Threading.Thread.Sleep (200);
+                                       retries--;
+                               }
+                       }
+                       ctx.ReportError ("File could not be opened: " + cacheFile, lastException);
+                       return null;
+               }
+               
+               void Load ()
+               {
+                       // The serializer can't be used because this file is reused in xbuild
+                       using (FileStream fs = OpenFile (FileAccess.Read)) {
+                               if (fs == null)
+                                       return;
+                               XmlTextReader xr = new XmlTextReader (fs);
+                               xr.MoveToContent ();
+                               xr.ReadStartElement ();
+                               xr.MoveToContent ();
+                               
+                               while (xr.NodeType == XmlNodeType.Element)
+                                       ReadPackage (xr);
+                       }
+               }
+               
+               public void Save ()
+               {
+                       // The serializer can't be used because this file is reused in xbuild
+                       lock (infos) {
+                               if (!hasChanges)
+                                       return;
+                               
+                               using (FileStream fs = OpenFile (FileAccess.Write)) {
+                                       if (fs == null)
+                                               return;
+                                       XmlTextWriter tw = new XmlTextWriter (new StreamWriter (fs));
+                                       tw.Formatting = Formatting.Indented;
+                                       
+                                       tw.WriteStartElement ("PcFileCache");
+                                       foreach (KeyValuePair<string,PackageInfo> file in infos) {
+                                               WritePackage (tw, file.Key, file.Value);
+                                       }
+                                       tw.WriteEndElement (); // PcFileCache
+                                       tw.Flush ();
+                                       
+                                       hasChanges = false;
+                               }
+                       }
+               }
+               
+               void WritePackage (XmlTextWriter tw, string file, PackageInfo pinfo)
+               {
+                       tw.WriteStartElement ("File");
+                       tw.WriteAttributeString ("path", file);
+                       tw.WriteAttributeString ("lastWriteTime", XmlConvert.ToString (pinfo.LastWriteTime, XmlDateTimeSerializationMode.Local));
+                       
+                       if (pinfo.IsValidPackage) {
+                               if (pinfo.Name != null)
+                                       tw.WriteAttributeString ("name", pinfo.Name);
+                               if (pinfo.Version != null)
+                                       tw.WriteAttributeString ("version", pinfo.Version);
+                               if (!string.IsNullOrEmpty (pinfo.Description))
+                                       tw.WriteAttributeString ("description", pinfo.Description);
+                               if (!pinfo.IsGacPackage)
+                                       tw.WriteAttributeString ("gacPackage", "false");
+                               if (pinfo.CustomData != null) {
+                                       foreach (KeyValuePair<string,string> cd in pinfo.CustomData)
+                                               tw.WriteAttributeString (cd.Key, cd.Value);
+                               }
+                               foreach (PackageAssemblyInfo asm in pinfo.Assemblies) {
+                                       tw.WriteStartElement ("Assembly");
+                                       tw.WriteAttributeString ("name", asm.Name);
+                                       tw.WriteAttributeString ("version", asm.Version);
+                                       tw.WriteAttributeString ("culture", asm.Culture);
+                                       tw.WriteAttributeString ("publicKeyToken", asm.PublicKeyToken);
+                                       tw.WriteAttributeString ("file", asm.File);
+                                       tw.WriteEndElement (); // Assembly
+                               }
+                       }
+                       tw.WriteEndElement (); // File
+               }
+               
+               void ReadPackage (XmlReader tr)
+               {
+                       PackageInfo pinfo = new PackageInfo ();
+                       string file = null;
+                       
+                       tr.MoveToFirstAttribute ();
+                       do {
+                               switch (tr.LocalName) {
+                                       case "path": file = tr.Value; break;
+                                       case "lastWriteTime": pinfo.LastWriteTime = XmlConvert.ToDateTime (tr.Value, XmlDateTimeSerializationMode.Local); break;
+                                       case "name": pinfo.Name = tr.Value; break;
+                                       case "version": pinfo.Version = tr.Value; break;
+                                       case "description": pinfo.Description = tr.Value; break;
+                                       case "gacPackage": pinfo.IsGacPackage = tr.Value != "false"; break;
+                                       default: pinfo.SetData (tr.LocalName, tr.Value); break;
+                               }
+                       } while (tr.MoveToNextAttribute ());
+                       
+                       tr.MoveToElement ();
+                       
+                       if (!tr.IsEmptyElement) {
+                               tr.ReadStartElement ();
+                               tr.MoveToContent ();
+                               while (tr.NodeType == XmlNodeType.Element) {
+                                       PackageAssemblyInfo asm = new PackageAssemblyInfo ();
+                                       asm.Name = tr.GetAttribute ("name");
+                                       asm.Version = tr.GetAttribute ("version");
+                                       asm.Culture = tr.GetAttribute ("culture");
+                                       asm.PublicKeyToken = tr.GetAttribute ("publicKeyToken");
+                                       asm.File = tr.GetAttribute ("file");
+                                       if (pinfo.Assemblies == null)
+                                               pinfo.Assemblies = new List<PackageAssemblyInfo> ();
+                                       asm.ParentPackage = pinfo;
+                                       pinfo.Assemblies.Add (asm);
+                                       tr.Read ();
+                                       tr.MoveToContent ();
+                               }
+                               tr.MoveToContent ();
+                               tr.ReadEndElement ();
+                       } else
+                               tr.Read ();
+                       tr.MoveToContent ();
+                       
+                       if (!pinfo.IsValidPackage || ctx.IsCustomDataComplete (file, pinfo))
+                               infos [file] = pinfo;
+               }
+               
+               public object SyncRoot {
+                       get { return infos; }
+               }
+               
+               
+               PackageInfo ParsePackageInfo (string pcfile)
+               {
+                       PackageInfo pinfo = new PackageInfo ();
+                       pinfo.Name = Path.GetFileNameWithoutExtension (pcfile);
+                       List<string> fullassemblies = null;
+                       bool gacPackageSet = false;
+                       
+                       PcFile file = new PcFile ();
+                       file.Load (pcfile);
+                       
+                       if (file.HasErrors)
+                               return pinfo;
+                       
+                       if (file.Libs != null && file.Libs.IndexOf (".dll") != -1) {
+                               if (file.Libs.IndexOf ("-lib:") != -1 || file.Libs.IndexOf ("/lib:") != -1) {
+                                       fullassemblies = GetAssembliesWithLibInfo (file.Libs);
+                               } else {
+                                       fullassemblies = GetAssembliesWithoutLibInfo (file.Libs);
+                               }
+                       }
+                       
+                       string value = file.GetVariable ("Libraries");
+                       if (!string.IsNullOrEmpty (value))
+                               fullassemblies = GetAssembliesFromLibrariesVar (value);
+                       
+                       pinfo.Version = file.Version;
+                       pinfo.Description = file.Description;
+
+                       value = file.GetVariable ("GacPackage");
+                       if (value != null) {
+                               value = value.ToLower ();
+                               pinfo.IsGacPackage = value == "yes" || value == "true";
+                               gacPackageSet = true;
+                       }
+       
+                       if (fullassemblies == null)
+                               return pinfo;
+                       
+                       string pcDir = Path.GetDirectoryName (pcfile);
+                       string monoPrefix = Path.GetDirectoryName (Path.GetDirectoryName (pcDir));
+                       monoPrefix = Path.GetFullPath (monoPrefix + Path.DirectorySeparatorChar + "lib" + Path.DirectorySeparatorChar + "mono" + Path.DirectorySeparatorChar);
+
+                       List<PackageAssemblyInfo> list = new List<PackageAssemblyInfo> ();
+                       foreach (string assembly in fullassemblies) {
+                               string asm;
+                               if (Path.IsPathRooted (assembly))
+                                       asm = Path.GetFullPath (assembly);
+                               else {
+                                       if (Path.GetDirectoryName (assembly).Length == 0) {
+                                               asm = assembly;
+                                       } else {
+                                               asm = Path.GetFullPath (Path.Combine (pcDir, assembly));
+                                       }
+                               }
+                               if (File.Exists (asm)) {
+                                       PackageAssemblyInfo pi = new PackageAssemblyInfo ();
+                                       pi.File = asm;
+                                       pi.ParentPackage = pinfo;
+                                       pi.UpdateFromFile (pi.File);
+                                       list.Add (pi);
+                                       if (!gacPackageSet && !asm.StartsWith (monoPrefix) && Path.IsPathRooted (asm)) {
+                                               // Assembly installed outside $(prefix)/lib/mono. It is most likely not a gac package.
+                                               gacPackageSet = true;
+                                               pinfo.IsGacPackage = false;
+                                       }
+                               }
+                       }
+                       pinfo.Assemblies = list;
+                       ctx.StoreCustomData (file, pinfo);
+                       
+                       return pinfo;
+               }
+               
+               private List<string> GetAssembliesWithLibInfo (string line)
+               {
+                       List<string> references = new List<string> ();
+                       List<string> libdirs = new List<string> ();
+                       List<string> retval = new List<string> ();
+                       foreach (string piece in line.Split (' ')) {
+                               if (piece.ToLower ().Trim ().StartsWith ("/r:") || piece.ToLower ().Trim ().StartsWith ("-r:")) {
+                                       references.Add (piece.Substring (3).Trim ());
+                               } else if (piece.ToLower ().Trim ().StartsWith ("/lib:") || piece.ToLower ().Trim ().StartsWith ("-lib:")) {
+                                       libdirs.Add (piece.Substring (5).Trim ());
+                               }
+                       }
+       
+                       foreach (string refrnc in references) {
+                               foreach (string libdir in libdirs) {
+                                       if (File.Exists (libdir + Path.DirectorySeparatorChar + refrnc)) {
+                                               retval.Add (libdir + Path.DirectorySeparatorChar + refrnc);
+                                       }
+                               }
+                       }
+       
+                       return retval;
+               }
+               
+               List<string> GetAssembliesFromLibrariesVar (string line)
+               {
+                       List<string> references = new List<string> ();
+                       foreach (string reference in line.Split (' ')) {
+                               if (!string.IsNullOrEmpty (reference))
+                                       references.Add (reference);
+                       }
+                       return references;
+               }
+       
+               private List<string> GetAssembliesWithoutLibInfo (string line)
+               {
+                       List<string> references = new List<string> ();
+                       foreach (string reference in line.Split (' ')) {
+                               if (reference.ToLower ().Trim ().StartsWith ("/r:") || reference.ToLower ().Trim ().StartsWith ("-r:")) {
+                                       string final_ref = reference.Substring (3).Trim ();
+                                       references.Add (final_ref);
+                               }
+                       }
+                       return references;
+               }
+               
+               public IEnumerable<string> GetPkgconfigPaths (string prefix, string pkgConfigPath, string pkgConfigLibdir)
+               {
+                       char[] sep = new char[] { Path.PathSeparator };
+                       
+                       string[] pkgConfigPaths = null;
+                       if (!String.IsNullOrEmpty (pkgConfigPath)) {
+                               pkgConfigPaths = pkgConfigPath.Split (sep, StringSplitOptions.RemoveEmptyEntries);
+                               if (pkgConfigPaths.Length == 0)
+                                       pkgConfigPaths = null;
+                       }
+                       
+                       string[] pkgConfigLibdirs = null;
+                       if (!String.IsNullOrEmpty (pkgConfigLibdir)) {
+                               pkgConfigLibdirs = pkgConfigLibdir.Split (sep, StringSplitOptions.RemoveEmptyEntries);
+                               if (pkgConfigLibdirs.Length == 0)
+                                       pkgConfigLibdirs = null;
+                       }
+                       
+                       if (prefix == null)
+                               prefix = PathUp (typeof (int).Assembly.Location, 4);
+                       
+                       IEnumerable<string> paths = GetUnfilteredPkgConfigDirs (pkgConfigPaths, pkgConfigLibdirs, new string [] { prefix });
+                       return NormaliseAndFilterPaths (paths, Environment.CurrentDirectory);
+               }
+               
+               IEnumerable<string> GetUnfilteredPkgConfigDirs (IEnumerable<string> pkgConfigPaths, IEnumerable<string> pkgConfigLibdirs, IEnumerable<string> systemPrefixes)
+               {
+                       if (pkgConfigPaths != null) {
+                               foreach (string dir in pkgConfigPaths)
+                                       yield return dir;
+                       }
+                       
+                       if (pkgConfigLibdirs != null) {
+                               foreach (string dir in pkgConfigLibdirs)
+                                       yield return dir;
+                       } else if (systemPrefixes != null) {
+                               string[] suffixes = new string [] {
+                                       Path.Combine ("lib", "pkgconfig"),
+                                       Path.Combine ("lib64", "pkgconfig"),
+                                       Path.Combine ("libdata", "pkgconfig"),
+                                       Path.Combine ("share", "pkgconfig"),
+                               };
+                               foreach (string prefix in systemPrefixes)
+                                       foreach (string suffix in suffixes)
+                                               yield return Path.Combine (prefix, suffix);
+                       }
+               }
+               
+               IEnumerable<string> NormaliseAndFilterPaths (IEnumerable<string> paths, string workingDirectory)
+               {
+                       HashSet<string> filtered = new HashSet<string> ();
+                       foreach (string p in paths) {
+                               string path = p;
+                               if (!Path.IsPathRooted (path))
+                                       path = Path.Combine (workingDirectory, path);
+                               path = Path.GetFullPath (path);
+                               if (!filtered.Add (path))
+                                       continue;
+                               try {
+                                       if (!Directory.Exists (path))
+                                               continue;
+                               } catch (IOException ex) {
+                                       ctx.ReportError ("Error checking for directory '" + path + "'.", ex);
+                               }
+                               yield return path;
+                       }
+               }
+               
+               static string PathUp (string path, int up)
+               {
+                       if (up == 0)
+                               return path;
+                       for (int i = path.Length -1; i >= 0; i--) {
+                               if (path[i] == Path.DirectorySeparatorChar) {
+                                       up--;
+                                       if (up == 0)
+                                               return path.Substring (0, i);
+                               }
+                       }
+                       return null;
+               }
+               
+               public static string NormalizeAsmName (string name)
+               {
+                       int i = name.ToLower ().IndexOf (", publickeytoken=null");
+                       if (i != -1)
+                               name = name.Substring (0, i).Trim ();
+                       i = name.ToLower ().IndexOf (", processorarchitecture=");
+                       if (i != -1)
+                               name = name.Substring (0, i).Trim ();
+                       return name;
+               }
+       }
+
+       internal class PcFile
+       {
+               Dictionary<string,string> variables = new Dictionary<string, string> ();
+               
+               public string FilePath { get; set; }
+               public string Name { get; set; }
+               public string Description { get; set; }
+               public string Version { get; set; }
+               public string Libs { get; set; }
+               public bool HasErrors { get; set; }
+               
+               public string GetVariable (string varName)
+               {
+                       string val;
+                       variables.TryGetValue (varName, out val);
+                       return val;
+               }
+               
+               public void Load (string pcfile)
+               {
+                       FilePath = pcfile;
+                       variables.Add ("pcfiledir", Path.GetDirectoryName (pcfile));
+                       using (StreamReader reader = new StreamReader (pcfile)) {
+                               string line;
+                               while ((line = reader.ReadLine ()) != null) {
+                                       int i = line.IndexOf (':');
+                                       int j = line.IndexOf ('=');
+                                       int k = System.Math.Min (i != -1 ? i : int.MaxValue, j != -1 ? j : int.MaxValue);
+                                       if (k == int.MaxValue)
+                                               continue;
+                                       string var = line.Substring (0, k).Trim ();
+                                       string value = line.Substring (k + 1).Trim ();
+                                       value = Evaluate (value);
+                                       
+                                       if (k == j) {
+                                               // Is variable
+                                               variables [var] = value;
+                                       }
+                                       else {
+                                               switch (var) {
+                                                       case "Name": Name = value; break;
+                                                       case "Description": Description = value; break;
+                                                       case "Version": Version = value; break;
+                                                       case "Libs": Libs = value; break;
+                                               }
+                                       }
+                               }
+                       }
+               }
+               
+               string Evaluate (string value)
+               {
+                       int i = value.IndexOf ("${");
+                       if (i == -1)
+                               return value;
+
+                       StringBuilder sb = new StringBuilder ();
+                       int last = 0;
+                       while (i != -1 && i < value.Length) {
+                               sb.Append (value.Substring (last, i - last));
+                               if (i == 0 || value [i - 1] != '$') {
+                                       // Evaluate if var is not escaped
+                                       i += 2;
+                                       int n = value.IndexOf ('}', i);
+                                       if (n == -1 || n == i) {
+                                               // Closing bracket not found or empty name
+                                               HasErrors = true;
+                                               return value;
+                                       }
+                                       string rname = value.Substring (i, n - i);
+                                       string rval;
+                                       if (variables.TryGetValue (rname, out rval))
+                                               sb.Append (rval);
+                                       else {
+                                               HasErrors = true;
+                                               return value;
+                                       }
+                                       i = n + 1;
+                                       last = i;
+                               } else
+                                       last = i++;
+                               
+                               if (i < value.Length - 1)
+                                       i = value.IndexOf ("${", i);
+                       }
+                       sb.Append (value.Substring (last, value.Length - last));
+                       return sb.ToString ();
+               }
+       }
+       
+       internal class PackageInfo
+       {
+               Dictionary<string,string> customData;
+               
+               public PackageInfo ()
+               {
+                       IsGacPackage = true;
+               }
+
+               public string Name { get; set; }
+               
+               public bool IsGacPackage { get; set; }
+               
+               public string Version { get; set; }
+               
+               public string Description { get; set; }
+               
+               internal List<PackageAssemblyInfo> Assemblies { get; set; }
+               
+               public string GetData (string name)
+               {
+                       if (customData == null)
+                               return null;
+                       string res;
+                       customData.TryGetValue (name, out res);
+                       return res;
+               }
+               
+               public void SetData (string name, string value)
+               {
+                       if (customData == null)
+                               customData = new Dictionary<string, string> ();
+                       customData [name] = value;
+               }
+               
+               internal Dictionary<string,string> CustomData {
+                       get { return customData; }
+               }
+               
+               internal DateTime LastWriteTime { get; set; }
+               
+               internal bool IsValidPackage {
+                       get { return Assemblies != null && Assemblies.Count > 0; }
+               }
+               
+               internal bool HasCustomData {
+                       get { return customData != null && customData.Count > 0; }
+               }
+       }
+       
+       class PackageAssemblyInfo
+       {
+               public string File { get; set; }
+               
+               public string Name;
+               
+               public string Version;
+               
+               public string Culture;
+               
+               public string PublicKeyToken;
+               
+               public string FullName {
+                       get {
+                               string fn = Name + ", Version=" + Version;
+                               if (!string.IsNullOrEmpty (Culture))
+                                       fn += ", Culture=" + Culture;
+                               if (!string.IsNullOrEmpty (PublicKeyToken))
+                                       fn += ", PublicKeyToken=" + PublicKeyToken;
+                               return fn;
+                       }
+               }
+               
+               public PackageInfo ParentPackage { get; set; }
+               
+               public void UpdateFromFile (string file)
+               {
+                       Update (System.Reflection.AssemblyName.GetAssemblyName (file));
+               }
+               
+               public void Update (System.Reflection.AssemblyName aname)
+               {
+                       Name = aname.Name;
+                       Version = aname.Version.ToString ();
+                       if (aname.CultureInfo != null) {
+                               if (aname.CultureInfo.LCID == System.Globalization.CultureInfo.InvariantCulture.LCID)
+                                       Culture = "neutral";
+                               else
+                                       Culture = aname.CultureInfo.Name;
+                       }
+                       string fn = aname.ToString ();
+                       string key = "publickeytoken=";
+                       int i = fn.ToLower().IndexOf (key) + key.Length;
+                       int j = fn.IndexOf (',', i);
+                       if (j == -1) j = fn.Length;
+                       PublicKeyToken = fn.Substring (i, j - i);
+               }
+       }
+}
index 9014198a19178999415061f1be8f4506b271e527..6927a01398acd8f9f3701bbd184d34a39e95bcb4 100644 (file)
@@ -122,8 +122,8 @@ namespace Microsoft.Build.Tasks {
                                                        resolved_ref.TaskItem.GetMetadata ("CopyLocal"));
 
                                        Log.LogMessage (MessageImportance.Low,
-                                                       "\tReference found at search path '{0}'",
-                                                       resolved_ref.FoundInSearchPathAsString ());
+                                                       "\tReference found at search path {0}",
+                                                       resolved_ref.FoundInSearchPathAsString);
 
                                        if (TryAddNewReference (tempResolvedFiles, resolved_ref) &&
                                                !IsFromGacOrTargetFramework (resolved_ref)) {
@@ -199,6 +199,8 @@ namespace Microsoft.Build.Tasks {
                                } else if (String.Compare (spath, "{CandidateAssemblyFiles}") == 0) {
                                        assembly_resolver.SearchLogger.WriteLine (
                                                        "Warning: {CandidateAssemblyFiles} not supported currently");
+                               } else if (String.Compare (spath, "{PkgConfig}") == 0) {
+                                       resolved = assembly_resolver.ResolvePkgConfigReference (item, specific_version);
                                } else {
                                        resolved = assembly_resolver.FindInDirectory (
                                                        item, spath,
@@ -332,8 +334,8 @@ namespace Microsoft.Build.Tasks {
                                        aname, resolved_ref.TaskItem.ItemSpec);
 
                                Log.LogMessage (MessageImportance.Low,
-                                               "\tReference found at search path '{0}'",
-                                               resolved_ref.FoundInSearchPathAsString ());
+                                               "\tReference found at search path {0}",
+                                               resolved_ref.FoundInSearchPathAsString);
 
                                if (resolved_ref.FoundInSearchPath == SearchPath.Directory) {
                                        // override CopyLocal with parent's val
@@ -350,8 +352,8 @@ namespace Microsoft.Build.Tasks {
                                } else {
                                        //gac or tgtfmwk
                                        Log.LogMessage (MessageImportance.Low,
-                                                       "\tThis is CopyLocal {0} as it is in the gac or one " +
-                                                       "of the target framework directories",
+                                                       "\tThis is CopyLocal {0} as it is in the gac," +
+                                                       "target framework directory or provided by a package.",
                                                        copy_local);
 
                                        TryAddNewReference (tempResolvedFiles, resolved_ref);
index 6119cf227086d51e3abcaed9aafa840bddc80222..1fa62149a8bc2aabc3b08c940b96637e26a025d4 100644 (file)
@@ -41,6 +41,8 @@ namespace Microsoft.Build.Tasks {
                public bool CopyLocal;
                public bool IsPrimary; //default: true
 
+               string found_search_path_string;
+
                public ResolvedReference (ITaskItem item, AssemblyName asm_name, bool copy_local, SearchPath search_path,
                                string original_item_spec)
                {
@@ -51,10 +53,20 @@ namespace Microsoft.Build.Tasks {
                        FoundInSearchPath = search_path;
 
                        TaskItem.SetMetadata ("OriginalItemSpec", original_item_spec);
-                       TaskItem.SetMetadata ("ResolvedFrom", FoundInSearchPathAsString ());
+                       TaskItem.SetMetadata ("ResolvedFrom", FoundInSearchPathToString ());
+               }
+
+               public string FoundInSearchPathAsString {
+                       get {
+                               if (found_search_path_string == null)
+                                       return FoundInSearchPathToString ();
+                               else
+                                       return found_search_path_string;
+                       }
+                       set { found_search_path_string = value; }
                }
 
-               public string FoundInSearchPathAsString ()
+               string FoundInSearchPathToString ()
                {
                        switch (FoundInSearchPath) {
                        case SearchPath.Gac:
@@ -69,6 +81,8 @@ namespace Microsoft.Build.Tasks {
                                return "{RawFileName}";
                        case SearchPath.Directory:
                                return TaskItem.ItemSpec;
+                       case SearchPath.PkgConfig:
+                               return "{PkgConfig}";
                        default:
                                throw new NotImplementedException (String.Format (
                                                "Implement me for SearchPath: {0}", FoundInSearchPath));
index 14e85e4f84c6bd4df0b0db53b1317fffbdcc5478..2d1da01f92c0a8cdfe5e8d59f51d49d92341a7a9 100644 (file)
@@ -35,7 +35,7 @@ using Microsoft.Build.Utilities;
 namespace Microsoft.Build.Tasks {
        public class TaskLoggingHelperExtension : TaskLoggingHelper {
                
-               public TaskLoggingHelperExtension ()
+               internal TaskLoggingHelperExtension ()
                        : base (null)
                {
                }
diff --git a/mcs/class/Microsoft.CSharp/Microsoft.CSharp.RuntimeBinder/CSharpBinder.cs b/mcs/class/Microsoft.CSharp/Microsoft.CSharp.RuntimeBinder/CSharpBinder.cs
new file mode 100644 (file)
index 0000000..f9bcfa7
--- /dev/null
@@ -0,0 +1,52 @@
+//
+// CSharpBinder.cs
+//
+// Authors:
+//     Marek Safar  <marek.safar@gmail.com>
+//
+// Copyright (C) 2009 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Dynamic;
+using System.Linq.Expressions;
+
+namespace Microsoft.CSharp.RuntimeBinder
+{
+       class CSharpBinder
+       {
+               public static DynamicMetaObject Bind (DynamicMetaObject target, DynamicMetaObject errorSuggestion, DynamicMetaObject[] args)
+               {
+                       return Bind (target, errorSuggestion);
+               }
+               
+               public static DynamicMetaObject Bind (DynamicMetaObject target, DynamicMetaObject errorSuggestion)
+               {
+            return errorSuggestion ??
+                   new DynamicMetaObject(
+                           Expression.Constant(new object ()),
+                           target.Restrictions.Merge(
+                               BindingRestrictions.GetTypeRestriction(
+                                   target.Expression, target.LimitType)));
+               }
+       }
+}
index 152b3cfd7c83d379010cc47da8b5a3153b1e84e5..d66ad0ed042cad285eaddba41924670747dc1e6c 100644 (file)
@@ -69,10 +69,9 @@ namespace Microsoft.CSharp.RuntimeBinder
                        return base.GetHashCode ();
                }
                
-               [MonoTODO]
                public override DynamicMetaObject FallbackGetMember (DynamicMetaObject target, DynamicMetaObject errorSuggestion)
                {
-                       throw new NotImplementedException ();                   
+                       return CSharpBinder.Bind (target, errorSuggestion);
                }
        }
 }
index 2f81f144bfa8111b40609554d2009188a4dbb618..a4e46f055873dcc3a0c380ba68ecbf37b421d46a 100644 (file)
@@ -77,10 +77,9 @@ namespace Microsoft.CSharp.RuntimeBinder
                        return base.GetHashCode ();
                }
                
-               [MonoTODO]
                public override DynamicMetaObject FallbackInvoke (DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion)
                {
-                       throw new NotImplementedException ();
+                       return CSharpBinder.Bind (target, errorSuggestion, args);
                }
        }
 }
index 15e57c5c2bb62fd29c2bd80cc28b8b2f4b01384e..0c8b9c503e7f1273a84ae42403dfd75a71622b75 100644 (file)
@@ -79,16 +79,17 @@ namespace Microsoft.CSharp.RuntimeBinder
                        return base.GetHashCode ();
                }
                
-               [MonoTODO]
                public override DynamicMetaObject FallbackInvoke (DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion)
                {
-                       throw new NotImplementedException ();
+                       var b = new CSharpInvokeBinder (flags, callingContext, argumentInfo);
+                       
+                       // TODO: Is errorSuggestion ever used?
+                       return b.Defer (target, args);
                }
                
-               [MonoTODO]
                public override DynamicMetaObject FallbackInvokeMember (DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion)
                {
-                       throw new NotImplementedException ();                   
+                       return CSharpBinder.Bind (target, errorSuggestion, args);
                }
                
                public IList<Type> TypeArguments {
index 79a2633dac744b7e15b1b6cebdcfedf53cc89bce..bd64be890e0b2217c974628a6daa110334a1826b 100644 (file)
@@ -1,3 +1,8 @@
+2009-08-10  Marek Safar <marek.safar@gmail.com>
+
+       * CSharpInvokeBinder.cs, CSharpGetMemberBinder.cs,
+       CSharpInvokeMemberBinder.cs: Defer fallback for now.
+
 2009-08-07  Marek Safar <marek.safar@gmail.com>
 
        * CSharpInvokeBinder.cs, CSharpGetIndexBinder.cs, Extensions.cs,
index 2d6ec6e30698b330b72f3dab81ddd581044c75e5..7c4756a703a17416eb0a106175a792cd1ed797aa 100644 (file)
@@ -19,3 +19,4 @@ Microsoft.CSharp.RuntimeBinder/CSharpUnaryOperationBinder.cs
 Microsoft.CSharp.RuntimeBinder/Extensions.cs
 Microsoft.CSharp.RuntimeBinder/RuntimeBinderException.cs
 Microsoft.CSharp.RuntimeBinder/RuntimeBinderInternalCompilerException.cs
+Microsoft.CSharp.RuntimeBinder/CSharpBinder.cs
index 5bd1e5a675adb4f703c6524bfff14bfe32e301d5..f475e5c55682a5fda189af12b10e247ccef6e785 100644 (file)
@@ -1,3 +1,8 @@
+2009-08-18  Michael Hutchinson  <mhutchinson@novell.com>
+
+       * Mono.Cecil/BaseAssemblyResolver.cs: Search GACs specified in the 
+         MONO_GAC_PREFIX environment variable.
+
 2009-08-06  Jb Evain  <jbevain@novell.com>
 
        * Mono.Cecil/BaseAssemblyResolver.cs:
index 83bd1b4d51a76f0ffe6c695852ddc5a5db0241e4..40ab0973fc1bbc9bd0605c2bdcd58555d8ed81cc 100644 (file)
@@ -37,6 +37,7 @@ namespace Mono.Cecil {
        public abstract class BaseAssemblyResolver : IAssemblyResolver {
 
                ArrayList m_directories;
+               string[] m_monoGacPaths;
 
                public void AddSearchDirectory (string directory)
                {
@@ -167,20 +168,50 @@ namespace Mono.Cecil {
                        return typeof (object).Assembly.GetType ("System.MonoType", false) != null;
                }
 
-               static AssemblyDefinition GetAssemblyInGac (AssemblyNameReference reference)
+               string[] MonoGacPaths {
+                       get {
+                               if (m_monoGacPaths == null)
+                                       m_monoGacPaths = GetDefaultMonoGacPaths ();
+                               return m_monoGacPaths;  
+                       }
+               }
+
+               static string[] GetDefaultMonoGacPaths ()
                {
-                       if (reference.PublicKeyToken == null || reference.PublicKeyToken.Length == 0)
-                               return null;
+                       ArrayList paths = new ArrayList ();
+                       string s = GetCurrentGacPath ();
+                       if (s != null)
+                               paths.Add (s);
+                       string gacPathsEnv = Environment.GetEnvironmentVariable ("MONO_GAC_PREFIX");
+                       if (gacPathsEnv != null && gacPathsEnv.Length > 0) {
+                               string[] gacPrefixes = gacPathsEnv.Split (Path.PathSeparator);
+                               foreach (string gacPrefix in gacPrefixes) {
+                                       if (gacPrefix != null && gacPrefix.Length > 0) {
+                                               string gac = Path.Combine (Path.Combine (Path.Combine (gacPrefix, "lib"), "mono"), "gac");
+                                               if (Directory.Exists (gac) && !paths.Contains (gac))
+                                                       paths.Add (gac);
+                                       }
+                               }
+                       }
+                       return (string[]) paths.ToArray (typeof (String));
+               }
 
-                       string currentGac = GetCurrentGacPath ();
-                       if (currentGac == null)
+               AssemblyDefinition GetAssemblyInGac (AssemblyNameReference reference)
+               {
+                       if (reference.PublicKeyToken == null || reference.PublicKeyToken.Length == 0)
                                return null;
 
                        if (OnMono ()) {
-                               string s = GetAssemblyFile (reference, currentGac);
-                               if (File.Exists (s))
-                                       return AssemblyFactory.GetAssembly (s);
+                               foreach (string gacpath in MonoGacPaths) {
+                                       string s = GetAssemblyFile (reference, gacpath);
+                                       if (File.Exists (s))
+                                               return AssemblyFactory.GetAssembly (s);
+                               }
                        } else {
+                               string currentGac = GetCurrentGacPath ();
+                               if (currentGac == null)
+                                       return null;
+
                                string [] gacs = new string [] {"GAC_MSIL", "GAC_32", "GAC"};
                                for (int i = 0; i < gacs.Length; i++) {
                                        string gac = Path.Combine (Directory.GetParent (currentGac).FullName, gacs [i]);
index c52183444b321a36933429cd6e75482d6c6ea8c8..56fda9fcb2cb94911bb9c7c069a143ecae06fe80 100644 (file)
@@ -1,3 +1,10 @@
+2009-08-17  Veerapuram Varadhan  <vvaradhan@novell.com>
+
+       ** Fixes #381151 NRE 
+       * Tds.cs (ProcessColumnInfo): Use Columns instead of creating a new list.
+       * TdsDataColumnCollection.cs (Clear, Add): New utility methods 
+       * Tdsxx.cs: ProcessColumnInfo definition changes.
+       
 2009-07-25  Veerapuram Varadhan  <vvaradhan@novell.com>
 
        * Tds70.cs (ProcessColumnInfo): Update the new DataTypeName property.
index df1a648c1d743e72dbfbf7571a06adc6942abf27..dbee05b3d78f5c520c17a5e6b1c3a6d73ed9e9b5 100644 (file)
@@ -215,7 +215,7 @@ namespace Mono.Data.Tds.Protocol
                                }
                        }
                }
-               
+
                private void SkipRow ()
                {
                        SkipToColumnIndex (Columns.Count);
@@ -420,6 +420,7 @@ namespace Mono.Data.Tds.Protocol
                        this.tdsVersion = tdsVersion;
                        this.packetSize = packetSize;
                        this.dataSource = dataSource;
+                       this.columns = new TdsDataColumnCollection ();
 
                        comm = new TdsComm (dataSource, port, packetSize, timeout, tdsVersion);
                }
@@ -1507,7 +1508,7 @@ namespace Mono.Data.Tds.Protocol
                        }
                }
 
-               protected abstract TdsDataColumnCollection ProcessColumnInfo ();
+               protected abstract void ProcessColumnInfo ();
 
                protected void ProcessColumnNames ()
                {
@@ -1619,6 +1620,7 @@ namespace Mono.Data.Tds.Protocol
                                database = newDB;
                                break;
                        case TdsEnvPacketSubType.CollationInfo:
+                               //Console.WriteLine ("ProcessEnvironmentChange::Got collation info");
                                cLen = comm.GetByte ();
                                collation = comm.GetBytes (cLen, true);
                                lcid = TdsCollation.LCID (collation);
@@ -1639,6 +1641,7 @@ namespace Mono.Data.Tds.Protocol
                        uint srvVersion = 0;
                        GetSubPacketLength ();
                        
+                       //Console.WriteLine ("ProcessLoginAck: B4 tdsVersion:{0}", tdsVersion);
                        // Valid only for a Login7 request
                        if (tdsVersion >= TdsVersion.tds70) {
                                comm.Skip (1);
@@ -1658,6 +1661,7 @@ namespace Mono.Data.Tds.Protocol
                                        tdsVersion = TdsVersion.tds90;
                                        break;
                                }
+                               //Console.WriteLine ("ProcessLoginAck: after tdsVersion:{0}", tdsVersion);                              
                        }
                        
                        if (tdsVersion >= TdsVersion.tds70) {
@@ -1809,7 +1813,8 @@ namespace Mono.Data.Tds.Protocol
                        case TdsPacketSubType.ColumnInfo:      // TDS 4.2
                        case TdsPacketSubType.ColumnMetadata:  // TDS 7.0
                        case TdsPacketSubType.RowFormat:       // TDS 5.0
-                               columns = ProcessColumnInfo ();
+                               Columns.Clear ();
+                               ProcessColumnInfo ();
                                break;
                        case TdsPacketSubType.ColumnDetail:
                                ProcessColumnDetail ();
index a0bdeb8b8ef84a96c3098587e77dcf1b66622c3f..fdca83087b1cc65b930f7218a481968462430fa5 100644 (file)
@@ -218,15 +218,13 @@ namespace Mono.Data.Tds.Protocol {
                        return IsConnected;
                }
 
-               protected override TdsDataColumnCollection ProcessColumnInfo ()
+               protected override void ProcessColumnInfo ()
                {
                        byte precision;
                        byte scale;
                        int totalLength = Comm.GetTdsShort ();
                        int bytesRead = 0;
 
-                       TdsDataColumnCollection result = new TdsDataColumnCollection ();
-
                        while (bytesRead < totalLength) {
                                scale = 0;
                                precision = 0;
@@ -273,7 +271,7 @@ namespace Mono.Data.Tds.Protocol {
                                }
 
                                TdsDataColumn col = new TdsDataColumn ();
-                               int index = result.Add (col);
+                               int index = Columns.Add (col);
 #if NET_2_0
                                col.ColumnType = columnType;
                                col.ColumnSize = bufLength;
@@ -294,8 +292,6 @@ namespace Mono.Data.Tds.Protocol {
                                col["AllowDBNull"] = nullable;
 #endif
                        }
-
-                       return result;
                }
 
                #endregion // Methods
index 11a73e177bc748556016bba5f849b2e74327ebcf..0d0e86c023dfa673bf24f67787908c105ffc978e 100644 (file)
@@ -460,10 +460,9 @@ namespace Mono.Data.Tds.Protocol
                        return id;
                }
 
-               protected override TdsDataColumnCollection ProcessColumnInfo ()
+               protected override void ProcessColumnInfo ()
                {
                        isSelectQuery = true; 
-                       TdsDataColumnCollection result = new TdsDataColumnCollection ();
                        /*int totalLength = */Comm.GetTdsShort ();
                        int count = Comm.GetTdsShort ();
                        for (int i = 0; i < count; i += 1) {
@@ -507,7 +506,7 @@ namespace Mono.Data.Tds.Protocol
                                        Comm.Skip (Comm.GetTdsShort ()); // Class ID
 
                                TdsDataColumn col = new TdsDataColumn ();
-                               result.Add (col);
+                               Columns.Add (col);
 #if NET_2_0
                                col.ColumnType = columnType;
                                col.ColumnName = columnName;
@@ -536,7 +535,6 @@ namespace Mono.Data.Tds.Protocol
                                col ["IsHidden"] = hidden;
 #endif
                        }
-                       return result;
                }
 
                private void SendParamFormat ()
index 609b1a9bef5da34e1dfe322cd040ca98385bcc87..a7c78a0f9e4a57fa2c780cb2b7edcc10072aade9 100644 (file)
@@ -243,6 +243,7 @@ namespace Mono.Data.Tds.Protocol
 
                        //Comm.Append (empty, 3, pad);
                        //byte[] version = {0x00, 0x0, 0x0, 0x71};
+                       //Console.WriteLine ("Version: {0}", ClientVersion[3]);
                        Comm.Append (ClientVersion); // TDS Version 7
                        Comm.Append ((int)this.PacketSize); // Set the Block Size
                        Comm.Append (empty, 3, pad);
@@ -564,13 +565,16 @@ namespace Mono.Data.Tds.Protocol
                                Comm.Append (param.Scale);
                        }
 
+                       
+                       /* VARADHAN: TDS 8 Debugging */
                        /*
-                        * VARADHAN: TDS 8 Debugging *
                        if (Collation != null) {
                                Console.WriteLine ("Collation is not null");
                                Console.WriteLine ("Column Type: {0}", colType);
                                Console.WriteLine ("Collation bytes: {0} {1} {2} {3} {4}", Collation[0], Collation[1], Collation[2],
                                                   Collation[3], Collation[4]);
+                       } else {
+                               Console.WriteLine ("Collation is null");
                        }
                        */
                        
@@ -761,9 +765,8 @@ namespace Mono.Data.Tds.Protocol
                        //return ColumnValues [0].ToString ();
                }
 
-               protected override TdsDataColumnCollection ProcessColumnInfo ()
+               protected override void ProcessColumnInfo ()
                {
-                       TdsDataColumnCollection result = new TdsDataColumnCollection ();
                        int numColumns = Comm.GetTdsShort ();
                        for (int i = 0; i < numColumns; i += 1) {
                                byte[] flagData = new byte[4];
@@ -816,7 +819,7 @@ namespace Mono.Data.Tds.Protocol
                                string columnName = Comm.GetString (Comm.GetByte ());
 
                                TdsDataColumn col = new TdsDataColumn ();
-                               result.Add (col);
+                               Columns.Add (col);
 #if NET_2_0
                                col.ColumnType = columnType;
                                col.ColumnName = columnName;
@@ -843,7 +846,6 @@ namespace Mono.Data.Tds.Protocol
                                col ["DataTypeName"] = Enum.GetName (typeof (TdsColumnType), xColumnType);
 #endif
                        }
-                       return result;
                }
 
                public override void Unprepare (string statementId)
index 4a57147609124c95f2d993ce74aaec919b4c0832..8f9273cf4adca9b117b0ba3c8426d9fc5d5c40fc 100644 (file)
@@ -67,18 +67,20 @@ namespace Mono.Data.Tds.Protocol {
 
                public override bool Connect (TdsConnectionParameters connectionParameters)
                {
+                       //Console.WriteLine ("Tds80::Connect");
                        return base.Connect (connectionParameters);
                }
 
-               protected override TdsDataColumnCollection ProcessColumnInfo ()
+               protected override void ProcessColumnInfo ()
                {
                        // We are connected to a Sql 7.0 server
-                       if (TdsVersion < TdsVersion.tds80)
-                               return base.ProcessColumnInfo ();
+                       if (TdsVersion < TdsVersion.tds80) {
+                               base.ProcessColumnInfo ();
+                               return;
+                       }
                        
                        // VARADHAN: TDS 8 Debugging
                        //Console.WriteLine ("Tds80.cs: In ProcessColumnInfo... entry");
-                       TdsDataColumnCollection result = new TdsDataColumnCollection ();
                        int numColumns = Comm.GetTdsShort ();
                        //Console.WriteLine ("Column count={0}", numColumns); TDS 8 Debugging
                        for (int i = 0; i < numColumns; i += 1) {
@@ -156,7 +158,7 @@ namespace Mono.Data.Tds.Protocol {
                                string columnName = Comm.GetString (Comm.GetByte ());
 
                                TdsDataColumn col = new TdsDataColumn ();
-                               result.Add (col);
+                               Columns.Add (col);
 #if NET_2_0
                                col.ColumnType = columnType;
                                col.ColumnName = columnName;
@@ -186,7 +188,6 @@ namespace Mono.Data.Tds.Protocol {
 #endif
                        }
                        //Console.WriteLine ("Tds80.cs: In ProcessColumnInfo... exit");  TDS 8 Debugging
-                       return result;
                }
 
                protected override void ProcessOutputParam ()
index 6f566e3e14b85317fc8d398147cf825530682f26..30636d4d2ba3f59ea00547158a9909ffe68a107c 100644 (file)
@@ -64,6 +64,7 @@ namespace Mono.Data.Tds.Protocol
 
                public virtual Tds CreateConnection (TdsConnectionInfo info)
                {
+                       //Console.WriteLine ("CreateConnection: TdsVersion:{0}", version);
                        switch (version)
                        {
                                case TdsVersion.tds42:
index 2551788073dc5f9cef6b9a3fe40635020758ccf0..f269d39b988262981d9ab2f70cb20c30afbfb726 100644 (file)
@@ -76,11 +76,22 @@ namespace Mono.Data.Tds.Protocol {
                        return index;
                }
 
+               public void Add (TdsDataColumnCollection columns)
+               {
+                       foreach (TdsDataColumn col in columns)
+                               Add (col);
+               }
+               
                public IEnumerator GetEnumerator ()
                {
                        return list.GetEnumerator ();
                }
 
+               public void Clear ()
+               {
+                       list.Clear ();
+               }
+               
                #endregion // Methods
        }
 }
index 265ee4a8e450e39386fec46d92ec3276814bad81..de784749e584eda5dd238d101f841992b17de08c 100644 (file)
@@ -1,3 +1,7 @@
+2009-08-18  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * System.Core.dll.sources : added a couple of sys.io.pipes files.
+
 2009-07-20  Jb Evain  <jbevain@novell.com>
 
        * Makefile: filter the valid profile on the framework version,
diff --git a/mcs/class/System.Core/Microsoft.Win32.SafeHandles/ChangeLog b/mcs/class/System.Core/Microsoft.Win32.SafeHandles/ChangeLog
new file mode 100755 (executable)
index 0000000..951b5b0
--- /dev/null
@@ -0,0 +1,3 @@
+2009-08-18  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * SafePipeHandle.cs : initial code.
diff --git a/mcs/class/System.Core/Microsoft.Win32.SafeHandles/SafePipeHandle.cs b/mcs/class/System.Core/Microsoft.Win32.SafeHandles/SafePipeHandle.cs
new file mode 100644 (file)
index 0000000..e2e8aae
--- /dev/null
@@ -0,0 +1,58 @@
+//
+// SafePipeHandle.cs
+//
+// Author:
+//     Atsushi Enomoto <atsushi@ximian.com>
+//
+// Copyright (C) 2009 Novell, Inc.  http://www.novell.com
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+using System;
+using System.IO;
+using System.Runtime.InteropServices;
+using System.Security.AccessControl;
+using System.Security.Permissions;
+using System.Security.Principal;
+
+namespace Microsoft.Win32.SafeHandles
+{
+       [HostProtection (SecurityAction.LinkDemand, MayLeakOnAbort = true)]
+       [SecurityPermission (SecurityAction.LinkDemand, UnmanagedCode = true)]
+       public sealed class SafePipeHandle : SafeHandleZeroOrMinusOneIsInvalid
+       {
+               public SafePipeHandle (IntPtr preexistingHandle, bool ownsHandle)
+                       : base (ownsHandle)
+               {
+                       handle = preexistingHandle;
+               }
+
+               protected override bool ReleaseHandle ()
+               {
+                       try {
+                               Marshal.FreeHGlobal (handle);
+                               return true;
+                       } catch (ArgumentException) {
+                               return false;
+                       }
+               }
+       }
+}
+
index 8a0c710faff28d49a7eff2e6100ca9395cc93912..89f27352b0b31913a21d176b3f6bc9b1d8a29295 100644 (file)
@@ -83,3 +83,21 @@ System.Security.Cryptography/SHA512CryptoServiceProvider.cs
 System.Threading/LockRecursionException.cs
 System.Threading/LockRecursionPolicy.cs
 System.Threading/ReaderWriterLockSlim.cs
+Microsoft.Win32.SafeHandles/SafePipeHandle.cs
+System.IO.Pipes/AnonymousPipeClientStream.cs
+System.IO.Pipes/AnonymousPipeServerStream.cs
+System.IO.Pipes/NamedPipeClientStream.cs
+System.IO.Pipes/NamedPipeServerStream.cs
+System.IO.Pipes/PipeAccessRights.cs
+System.IO.Pipes/PipeAccessRule.cs
+System.IO.Pipes/PipeAuditRule.cs
+System.IO.Pipes/PipeDirection.cs
+System.IO.Pipes/PipeInterfaces.cs
+System.IO.Pipes/PipeOptions.cs
+System.IO.Pipes/PipeSecurity.cs
+System.IO.Pipes/PipeStream.cs
+System.IO.Pipes/PipeStreamImpersonationWorker.cs
+System.IO.Pipes/PipeTransmissionMode.cs
+System.IO.Pipes/PipeUnix.cs
+System.IO.Pipes/PipeWin32.cs
+System.IO/HandleInheritability.cs
diff --git a/mcs/class/System.Core/System.IO.Pipes/AnonymousPipeClientStream.cs b/mcs/class/System.Core/System.IO.Pipes/AnonymousPipeClientStream.cs
new file mode 100644 (file)
index 0000000..3913273
--- /dev/null
@@ -0,0 +1,88 @@
+//
+// AnonymousPipeClientStream.cs
+//
+// Author:
+//     Atsushi Enomoto <atsushi@ximian.com>
+//
+// Copyright (C) 2009 Novell, Inc.  http://www.novell.com
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+using System;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Security.AccessControl;
+using System.Security.Permissions;
+using System.Security.Principal;
+using Microsoft.Win32.SafeHandles;
+
+namespace System.IO.Pipes
+{
+       [MonoTODO ("Anonymous pipes are not working even on win32, due to some access authorization issue")]
+       [HostProtection (SecurityAction.LinkDemand, MayLeakOnAbort = true)]
+       public sealed class AnonymousPipeClientStream : PipeStream
+       {
+               static SafePipeHandle ToSafePipeHandle (string pipeHandleAsString)
+               {
+                       if (pipeHandleAsString == null)
+                               throw new ArgumentNullException ("pipeHandleAsString");
+                       // We use int64 for safety
+                       return new SafePipeHandle (new IntPtr (long.Parse (pipeHandleAsString, NumberFormatInfo.InvariantInfo)), false);
+               }
+
+               //IAnonymousPipeClient impl;
+
+               public AnonymousPipeClientStream (string pipeHandleAsString)
+                       : this (PipeDirection.In, pipeHandleAsString)
+               {
+               }
+
+               public AnonymousPipeClientStream (PipeDirection direction, string pipeHandleAsString)
+                       : this (direction, ToSafePipeHandle (pipeHandleAsString))
+               {
+               }
+
+               public AnonymousPipeClientStream (PipeDirection direction,SafePipeHandle safePipeHandle)
+                       : base (direction, DefaultBufferSize)
+               {
+                       /*
+                       if (IsWindows)
+                               impl = new Win32AnonymousPipeClient (this, safePipeHandle);
+                       else
+                               impl = new UnixAnonymousPipeClient (this, safePipeHandle);
+                       */
+
+                       InitializeHandle (safePipeHandle, false, false);
+                       IsConnected = true;
+               }
+
+               public override PipeTransmissionMode ReadMode {
+                       set {
+                               if (value == PipeTransmissionMode.Message)
+                                       throw new NotSupportedException ();
+                       }
+               }
+
+               public override PipeTransmissionMode TransmissionMode {
+                       get { return PipeTransmissionMode.Byte; }
+               }
+       }
+}
diff --git a/mcs/class/System.Core/System.IO.Pipes/AnonymousPipeServerStream.cs b/mcs/class/System.Core/System.IO.Pipes/AnonymousPipeServerStream.cs
new file mode 100644 (file)
index 0000000..96de7dc
--- /dev/null
@@ -0,0 +1,132 @@
+//
+// AnonymousPipeServerStream.cs
+//
+// Author:
+//     Atsushi Enomoto <atsushi@ximian.com>
+//
+// Copyright (C) 2009 Novell, Inc.  http://www.novell.com
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+using System;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Security.AccessControl;
+using System.Security.Permissions;
+using System.Security.Principal;
+using Microsoft.Win32.SafeHandles;
+
+namespace System.IO.Pipes
+{
+       [MonoTODO ("Anonymous pipes are not working even on win32, due to some access authorization issue")]
+       [HostProtection (SecurityAction.LinkDemand, MayLeakOnAbort = true)]
+       public sealed class AnonymousPipeServerStream : PipeStream
+       {
+               public AnonymousPipeServerStream ()
+                       : this (PipeDirection.Out)
+               {
+               }
+
+               public AnonymousPipeServerStream (PipeDirection direction)
+                       : this (direction, HandleInheritability.None)
+               {
+               }
+
+               public AnonymousPipeServerStream (PipeDirection direction, HandleInheritability inheritability)
+                       : this (direction, inheritability, DefaultBufferSize)
+               {
+               }
+
+               public AnonymousPipeServerStream (PipeDirection direction, HandleInheritability inheritability, int bufferSize)
+                       : this (direction, inheritability, bufferSize, null)
+               {
+               }
+
+               public AnonymousPipeServerStream (PipeDirection direction, HandleInheritability inheritability, int bufferSize, PipeSecurity pipeSecurity)
+                       : base (direction, bufferSize)
+               {
+                       if (pipeSecurity != null)
+                               throw ThrowACLException ();
+
+                       if (direction == PipeDirection.InOut)
+                               throw new NotSupportedException ("Anonymous pipe direction can only be either in or out.");
+
+                       if (IsWindows)
+                               impl = new Win32AnonymousPipeServer (this,direction, inheritability, bufferSize);
+                       else
+                               impl = new UnixAnonymousPipeServer (this,direction, inheritability, bufferSize);
+
+                       InitializeHandle (impl.Handle, false, false);
+                       IsConnected = true;
+               }
+
+               [MonoTODO]
+               public AnonymousPipeServerStream (PipeDirection direction, SafePipeHandle serverSafePipeHandle, SafePipeHandle clientSafePipeHandle)
+                       : base (direction, DefaultBufferSize)
+               {
+                       if (serverSafePipeHandle == null)
+                               throw new ArgumentNullException ("serverSafePipeHandle");
+                       if (clientSafePipeHandle == null)
+                               throw new ArgumentNullException ("clientSafePipeHandle");
+
+                       if (direction == PipeDirection.InOut)
+                               throw new NotSupportedException ("Anonymous pipe direction can only be either in or out.");
+
+                       if (IsWindows)
+                               impl = new Win32AnonymousPipeServer (this, serverSafePipeHandle, clientSafePipeHandle);
+                       else
+                               impl = new UnixAnonymousPipeServer (this, serverSafePipeHandle, clientSafePipeHandle);
+
+                       InitializeHandle (serverSafePipeHandle, true, false);
+                       IsConnected = true;
+
+                       ClientSafePipeHandle = clientSafePipeHandle;
+               }
+
+               IAnonymousPipeServer impl;
+
+               [MonoTODO]
+               public SafePipeHandle ClientSafePipeHandle { get; private set; }
+
+               public override PipeTransmissionMode ReadMode {
+                       set {
+                               if (value == PipeTransmissionMode.Message)
+                                       throw new NotSupportedException ();
+                       }
+               }
+
+               public override PipeTransmissionMode TransmissionMode {
+                       get { return PipeTransmissionMode.Byte; }
+               }
+
+               [MonoTODO]
+               public void DisposeLocalCopyOfClientHandle ()
+               {
+                       impl.DisposeLocalCopyOfClientHandle ();
+               }
+
+               public string GetClientHandleAsString ()
+               {
+                       // We use int64 for safety.
+                       return impl.Handle.DangerousGetHandle ().ToInt64 ().ToString (NumberFormatInfo.InvariantInfo);
+               }
+       }
+}
diff --git a/mcs/class/System.Core/System.IO.Pipes/ChangeLog b/mcs/class/System.Core/System.IO.Pipes/ChangeLog
new file mode 100755 (executable)
index 0000000..f252ed4
--- /dev/null
@@ -0,0 +1,9 @@
+2009-08-18  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * AnonymousPipeClientStream.cs, AnonymousPipeServerStream.cs,
+         NamedPipeClientStream.cs, NamedPipeServerStream.cs
+         PipeAccessRights.cs, PipeAccessRule.cs, PipeAuditRule.cs,
+         PipeDirection.cs, PipeInterfaces.cs, PipeOptions.cs,
+         PipeSecurity.cs, PipeStream.cs, PipeStreamImpersonationWorker.cs,
+         PipeTransmissionMode.cs, PipeUnix.cs, PipeWin32.cs :
+         initial implementation, so far with win32 impl.
diff --git a/mcs/class/System.Core/System.IO.Pipes/NamedPipeClientStream.cs b/mcs/class/System.Core/System.IO.Pipes/NamedPipeClientStream.cs
new file mode 100644 (file)
index 0000000..43cb0a0
--- /dev/null
@@ -0,0 +1,123 @@
+//
+// NamedPipeClientStream.cs
+//
+// Author:
+//     Atsushi Enomoto <atsushi@ximian.com>
+//
+// Copyright (C) 2009 Novell, Inc.  http://www.novell.com
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+using System;
+using System.ComponentModel;
+using System.IO;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Security.AccessControl;
+using System.Security.Permissions;
+using System.Security.Principal;
+using System.Text;
+using Microsoft.Win32;
+using Microsoft.Win32.SafeHandles;
+
+namespace System.IO.Pipes
+{
+       [MonoTODO ("working only on win32 right now")]
+       [HostProtection (SecurityAction.LinkDemand, MayLeakOnAbort = true)]
+       public sealed class NamedPipeClientStream : PipeStream
+       {
+               public NamedPipeClientStream (string pipeName)
+                       : this (".", pipeName)
+               {
+               }
+
+               public NamedPipeClientStream (string serverName, string pipeName)
+                       : this (serverName, pipeName, PipeDirection.InOut)
+               {
+               }
+
+               public NamedPipeClientStream (string serverName, string pipeName, PipeDirection direction)
+                       : this (serverName, pipeName, direction, PipeOptions.None)
+               {
+               }
+
+               public NamedPipeClientStream (string serverName, string pipeName, PipeDirection direction, PipeOptions options)
+                       : this (serverName, pipeName, direction, options, TokenImpersonationLevel.None)
+               {
+               }
+
+               public NamedPipeClientStream (string serverName, string pipeName, PipeDirection direction, PipeOptions options, TokenImpersonationLevel impersonationLevel)
+                       : this (serverName, pipeName, direction, options, impersonationLevel, HandleInheritability.None)
+               {
+               }
+
+               public NamedPipeClientStream (string serverName, string pipeName, PipeDirection direction, PipeOptions options, TokenImpersonationLevel impersonationLevel, HandleInheritability inheritability)
+                       : this (serverName, pipeName, ToAccessRights (direction), options, impersonationLevel, inheritability)
+               {
+               }
+
+               public NamedPipeClientStream (PipeDirection direction, bool isAsync, bool isConnected, SafePipeHandle safePipeHandle)
+                       : base (direction, DefaultBufferSize)
+               {
+                       if (IsWindows)
+                               impl = new Win32NamedPipeClient (this, safePipeHandle);
+                       else
+                               impl = new UnixNamedPipeClient (this, safePipeHandle);
+                       IsConnected = isConnected;
+                       InitializeHandle (safePipeHandle, true, isAsync);
+               }
+
+               public NamedPipeClientStream (string serverName, string pipeName, PipeAccessRights desiredAccessRights, PipeOptions options, TokenImpersonationLevel impersonationLevel, HandleInheritability inheritability)
+                       : base (ToDirection (desiredAccessRights), DefaultBufferSize)
+               {
+                       if (impersonationLevel != TokenImpersonationLevel.None ||
+                           inheritability != HandleInheritability.None)
+                               throw ThrowACLException ();
+
+                       if (IsWindows)
+                               impl = new Win32NamedPipeClient (this, serverName, pipeName, desiredAccessRights, options, inheritability);
+                       else
+                               impl = new UnixNamedPipeClient (this, serverName, pipeName, desiredAccessRights, options, inheritability);
+               }
+
+               INamedPipeClient impl;
+
+               public void Connect ()
+               {
+                       impl.Connect ();
+                       InitializeHandle (impl.Handle, false, impl.IsAsync);
+                       IsConnected = true;
+               }
+
+               public void Connect (int timeout)
+               {
+                       impl.Connect (timeout);
+                       InitializeHandle (impl.Handle, false, impl.IsAsync);
+                       IsConnected = true;
+               }
+
+               public int NumberOfServerInstances {
+                       get {
+                               CheckPipePropertyOperations ();
+                               return impl.NumberOfServerInstances;
+                       }
+               }
+       }
+}
diff --git a/mcs/class/System.Core/System.IO.Pipes/NamedPipeServerStream.cs b/mcs/class/System.Core/System.IO.Pipes/NamedPipeServerStream.cs
new file mode 100644 (file)
index 0000000..1f6bdae
--- /dev/null
@@ -0,0 +1,157 @@
+//
+// NamedPipeServerStream.cs
+//
+// Author:
+//     Atsushi Enomoto <atsushi@ximian.com>
+//
+// Copyright (C) 2009 Novell, Inc.  http://www.novell.com
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+using Microsoft.Win32.SafeHandles;
+using System;
+using System.IO;
+using System.Linq;
+using System.Security.AccessControl;
+using System.Security.Permissions;
+using System.Security.Principal;
+
+namespace System.IO.Pipes
+{
+       [MonoTODO ("working only on win32 right now")]
+       [HostProtection (SecurityAction.LinkDemand, MayLeakOnAbort = true)]
+       public sealed class NamedPipeServerStream : PipeStream
+       {
+               [MonoTODO]
+               public const int MaxAllowedServerInstances = 1;
+
+               public NamedPipeServerStream (string pipeName)
+                       : this (pipeName, PipeDirection.InOut)
+               {
+               }
+
+               public NamedPipeServerStream (string pipeName, PipeDirection direction)
+                       : this (pipeName, direction, 1)
+               {
+               }
+
+               public NamedPipeServerStream (string pipeName, PipeDirection direction, int maxNumberOfServerInstances)
+                       : this (pipeName, direction, maxNumberOfServerInstances, PipeTransmissionMode.Byte)
+               {
+               }
+
+               public NamedPipeServerStream (string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode)
+                       : this (pipeName, direction, maxNumberOfServerInstances, transmissionMode, PipeOptions.None)
+               {
+               }
+
+               public NamedPipeServerStream (string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options)
+                       : this (pipeName, direction, maxNumberOfServerInstances, transmissionMode, options, DefaultBufferSize, DefaultBufferSize)
+               {
+               }
+
+               public NamedPipeServerStream (string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize)
+                       : this (pipeName, direction, maxNumberOfServerInstances, transmissionMode, options, inBufferSize, outBufferSize, null)
+               {
+               }
+
+               public NamedPipeServerStream (string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize, PipeSecurity pipeSecurity)
+                       : this (pipeName, direction, maxNumberOfServerInstances, transmissionMode, options, inBufferSize, outBufferSize, pipeSecurity, HandleInheritability.None)
+               {
+               }
+
+               public NamedPipeServerStream (string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize, PipeSecurity pipeSecurity, HandleInheritability inheritability)
+                       : this (pipeName, direction, maxNumberOfServerInstances, transmissionMode, options, inBufferSize, outBufferSize, pipeSecurity, inheritability, PipeAccessRights.ReadData | PipeAccessRights.WriteData)
+               {
+               }
+
+               [MonoTODO]
+               public NamedPipeServerStream (string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize, PipeSecurity pipeSecurity, HandleInheritability inheritability, PipeAccessRights additionalAccessRights)
+                       : base (direction, transmissionMode, outBufferSize)
+               {
+                       if (pipeSecurity != null)
+                               throw ThrowACLException ();
+                       var rights = ToAccessRights (direction) | additionalAccessRights;
+                       // FIXME: reject some rights declarations (for ACL).
+
+                       if (IsWindows)
+                               impl = new Win32NamedPipeServer (this, pipeName, maxNumberOfServerInstances, transmissionMode, rights, options, inBufferSize, outBufferSize, inheritability);
+                       else
+                               impl = new UnixNamedPipeServer (this, pipeName, maxNumberOfServerInstances, transmissionMode, rights, options, inBufferSize, outBufferSize, inheritability);
+
+                       InitializeHandle (impl.Handle, false, (options & PipeOptions.Asynchronous) != PipeOptions.None);
+               }
+
+               public NamedPipeServerStream (PipeDirection direction, bool isAsync, bool isConnected, SafePipeHandle safePipeHandle)
+                       : base (direction, DefaultBufferSize)
+               {
+                       if (IsWindows)
+                               impl = new Win32NamedPipeServer (this, safePipeHandle);
+                       else
+                               impl = new UnixNamedPipeServer (this, safePipeHandle);
+                       IsConnected = isConnected;
+                       InitializeHandle (safePipeHandle, true, isAsync);
+               }
+
+               INamedPipeServer impl;
+
+               public void Disconnect ()
+               {
+                       impl.Disconnect ();
+               }
+
+               [MonoTODO]
+               [SecurityPermission (SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlPrincipal)]
+               public void RunAsClient (PipeStreamImpersonationWorker impersonationWorker)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public void WaitForConnection ()
+               {
+                       impl.WaitForConnection ();
+                       IsConnected = true;
+               }
+
+               [MonoTODO]
+               [SecurityPermission (SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlPrincipal)]
+               public string GetImpersonationUserName ()
+               {
+                       throw new NotImplementedException ();
+               }
+
+               // async operations
+
+               Action wait_connect_delegate;
+
+               [HostProtection (SecurityAction.LinkDemand, ExternalThreading = true)]
+               public IAsyncResult BeginWaitForConnection (AsyncCallback callback, object state)
+               {
+                       if (wait_connect_delegate == null)
+                               wait_connect_delegate = new Action (WaitForConnection);
+                       return wait_connect_delegate.BeginInvoke (callback, state);
+               }
+
+               public void EndWaitForConnection (IAsyncResult asyncResult)
+               {
+                       wait_connect_delegate.EndInvoke (asyncResult);
+               }
+       }
+}
diff --git a/mcs/class/System.Core/System.IO.Pipes/PipeAccessRights.cs b/mcs/class/System.Core/System.IO.Pipes/PipeAccessRights.cs
new file mode 100644 (file)
index 0000000..544ab3e
--- /dev/null
@@ -0,0 +1,25 @@
+namespace System.IO.Pipes
+{
+       [Flags]
+       public enum PipeAccessRights
+       {
+               // FIXME: values are not verified at all
+               ReadData = 1,
+               WriteData = 2,
+               ReadAttributes = 4,
+               WriteAttributes = 8,
+               ReadExtendedAttributes = 16,
+               WriteExtendedAttributes = 32,
+               CreateNewInstance = 64,
+               Delete = 128,
+               ReadPermissions = 256,
+               ChangePermissions = 512,
+               TakeOwnership = 1024,
+               Synchronize = 2048,
+               FullControl = ReadWrite | AccessSystemSecurity,
+               Read = ReadData | ReadAttributes | ReadExtendedAttributes | ReadPermissions,
+               Write = WriteData | WriteAttributes | WriteExtendedAttributes | ChangePermissions,
+               ReadWrite = Read | Write,
+               AccessSystemSecurity = ReadPermissions | ChangePermissions | TakeOwnership
+       }
+}
diff --git a/mcs/class/System.Core/System.IO.Pipes/PipeAccessRule.cs b/mcs/class/System.Core/System.IO.Pipes/PipeAccessRule.cs
new file mode 100644 (file)
index 0000000..d0d3993
--- /dev/null
@@ -0,0 +1,57 @@
+//
+// PipeAccessRule.cs
+//
+// Author:
+//     Atsushi Enomoto <atsushi@ximian.com>
+//
+// Copyright (C) 2009 Novell, Inc.  http://www.novell.com
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+using System;
+using System.IO;
+using System.Linq;
+using System.Security.AccessControl;
+using System.Security.Permissions;
+using System.Security.Principal;
+
+namespace System.IO.Pipes
+{
+       [HostProtection (SecurityAction.LinkDemand, MayLeakOnAbort = true)]
+       public sealed class PipeAccessRule : AccessRule
+       {
+               [MonoNotSupported ("ACL is not supported in Mono")]
+               public PipeAccessRule (IdentityReference identity, PipeAccessRights rights, AccessControlType type)
+                       : base (identity, 0, false, InheritanceFlags.None, PropagationFlags.None, type)
+               {
+                       throw new NotImplementedException ("ACL is not supported in Mono");
+               }
+
+               [MonoNotSupported ("ACL is not supported in Mono")]
+               public PipeAccessRule (string identity, PipeAccessRights rights, AccessControlType type)
+                       : this ((IdentityReference) null, rights, type)
+               {
+                       throw new NotImplementedException ("ACL is not supported in Mono");
+               }
+
+               [MonoNotSupported ("ACL is not supported in Mono")]
+               public PipeAccessRights PipeAccessRights { get; private set; }
+       }
+}
diff --git a/mcs/class/System.Core/System.IO.Pipes/PipeAuditRule.cs b/mcs/class/System.Core/System.IO.Pipes/PipeAuditRule.cs
new file mode 100644 (file)
index 0000000..2678dc7
--- /dev/null
@@ -0,0 +1,57 @@
+//
+// PipeAuditRule.cs
+//
+// Author:
+//     Atsushi Enomoto <atsushi@ximian.com>
+//
+// Copyright (C) 2009 Novell, Inc.  http://www.novell.com
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+using System;
+using System.IO;
+using System.Linq;
+using System.Security.AccessControl;
+using System.Security.Permissions;
+using System.Security.Principal;
+
+namespace System.IO.Pipes
+{
+       [HostProtection (SecurityAction.LinkDemand, MayLeakOnAbort = true)]
+       public sealed class PipeAuditRule : AuditRule
+       {
+               [MonoNotSupported ("ACL is not supported in Mono")]
+               public PipeAuditRule (IdentityReference identity, PipeAccessRights rights, AuditFlags flags)
+                       : base (identity, 0, false, InheritanceFlags.None, PropagationFlags.None, flags)
+               {
+                       throw new NotImplementedException ("ACL is not supported in Mono");
+               }
+
+               [MonoNotSupported ("ACL is not supported in Mono")]
+               public PipeAuditRule (string identity, PipeAccessRights rights, AuditFlags flags)
+                       : this ((IdentityReference) null, rights, flags)
+               {
+                       throw new NotImplementedException ("ACL is not supported in Mono");
+               }
+
+               [MonoNotSupported ("ACL is not supported in Mono")]
+               public PipeAccessRights PipeAccessRights { get; private set; }
+       }
+}
diff --git a/mcs/class/System.Core/System.IO.Pipes/PipeDirection.cs b/mcs/class/System.Core/System.IO.Pipes/PipeDirection.cs
new file mode 100644 (file)
index 0000000..1e5ab78
--- /dev/null
@@ -0,0 +1,10 @@
+namespace System.IO.Pipes
+{
+       [Serializable]
+       public enum PipeDirection
+       {
+               In = 1,
+               Out = 2,
+               InOut = 3
+       }
+}
diff --git a/mcs/class/System.Core/System.IO.Pipes/PipeInterfaces.cs b/mcs/class/System.Core/System.IO.Pipes/PipeInterfaces.cs
new file mode 100644 (file)
index 0000000..9ab7404
--- /dev/null
@@ -0,0 +1,36 @@
+using Microsoft.Win32.SafeHandles;
+
+namespace System.IO.Pipes
+{
+       // Common interfaces
+
+       interface IPipe
+       {
+               SafePipeHandle Handle { get; }
+               void WaitForPipeDrain ();
+       }
+
+       interface IAnonymousPipeClient : IPipe
+       {
+       }
+
+       interface IAnonymousPipeServer : IPipe
+       {
+               SafePipeHandle ClientHandle { get; }
+               void DisposeLocalCopyOfClientHandle ();
+       }
+
+       interface INamedPipeClient : IPipe
+       {
+               void Connect ();
+               void Connect (int timeout);
+               int NumberOfServerInstances { get; }
+               bool IsAsync { get; }
+       }
+
+       interface INamedPipeServer : IPipe
+       {
+               void Disconnect ();
+               void WaitForConnection ();
+       }
+}
diff --git a/mcs/class/System.Core/System.IO.Pipes/PipeOptions.cs b/mcs/class/System.Core/System.IO.Pipes/PipeOptions.cs
new file mode 100644 (file)
index 0000000..9532b05
--- /dev/null
@@ -0,0 +1,11 @@
+namespace System.IO.Pipes
+{
+       [Serializable]
+       [Flags]
+       public enum PipeOptions
+       {
+               None = 0,
+               WriteThrough,
+               Asynchronous
+       }
+}
diff --git a/mcs/class/System.Core/System.IO.Pipes/PipeSecurity.cs b/mcs/class/System.Core/System.IO.Pipes/PipeSecurity.cs
new file mode 100644 (file)
index 0000000..d21178a
--- /dev/null
@@ -0,0 +1,147 @@
+//
+// PipeSecurity.cs
+//
+// Author:
+//     Atsushi Enomoto <atsushi@ximian.com>
+//
+// Copyright (C) 2009 Novell, Inc.  http://www.novell.com
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+using System;
+using System.IO;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Security.AccessControl;
+using System.Security.Permissions;
+using System.Security.Principal;
+
+namespace System.IO.Pipes
+{
+       [MonoNotSupported ("ACL is not supported in Mono")]
+       [HostProtection (SecurityAction.LinkDemand, MayLeakOnAbort = true)]
+       public class PipeSecurity : NativeObjectSecurity
+       {
+               [MonoNotSupported ("ACL is not supported in Mono")]
+               public PipeSecurity ()
+                       : base (false, ResourceType.FileObject)
+               {
+                       throw new NotImplementedException ("ACL is not supported in Mono");
+               }
+
+               public override Type AccessRightType {
+                       get { return typeof (PipeAccessRights); }
+               }
+
+               public override Type AccessRuleType {
+                       get { return typeof (PipeAccessRule); }
+               }
+
+               public override Type AuditRuleType {
+                       get { return typeof (PipeAuditRule); }
+               }
+
+               [MonoNotSupported ("ACL is not supported in Mono")]
+               public override AccessRule AccessRuleFactory (IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type)
+               {
+                       throw new NotImplementedException ("ACL is not supported in Mono");
+               }
+
+               [MonoNotSupported ("ACL is not supported in Mono")]
+               public void AddAccessRule (PipeAccessRule rule)
+               {
+                       throw new NotImplementedException ("ACL is not supported in Mono");
+               }
+
+               [MonoNotSupported ("ACL is not supported in Mono")]
+               public void AddAuditRule (PipeAuditRule rule)
+               {
+                       throw new NotImplementedException ("ACL is not supported in Mono");
+               }
+
+               [MonoNotSupported ("ACL is not supported in Mono")]
+               public override sealed AuditRule AuditRuleFactory (IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AuditFlags flags)
+               {
+                       throw new NotImplementedException ("ACL is not supported in Mono");
+               }
+
+               [MonoNotSupported ("ACL is not supported in Mono")]
+               [SecurityPermission (SecurityAction.Assert, UnmanagedCode = true)]
+               protected internal void Persist (SafeHandle handle)
+               {
+                       throw new NotImplementedException ("ACL is not supported in Mono");
+               }
+
+               [MonoNotSupported ("ACL is not supported in Mono")]
+               [SecurityPermission (SecurityAction.Assert, UnmanagedCode = true)]
+               protected internal void Persist (string name)
+               {
+                       throw new NotImplementedException ("ACL is not supported in Mono");
+               }
+
+               [MonoNotSupported ("ACL is not supported in Mono")]
+               public bool RemoveAccessRule (PipeAccessRule rule)
+               {
+                       throw new NotImplementedException ("ACL is not supported in Mono");
+               }
+
+               [MonoNotSupported ("ACL is not supported in Mono")]
+               public void RemoveAccessRuleSpecific (PipeAccessRule rule)
+               {
+                       throw new NotImplementedException ("ACL is not supported in Mono");
+               }
+
+               [MonoNotSupported ("ACL is not supported in Mono")]
+               public bool RemoveAuditRule (PipeAuditRule rule)
+               {
+                       throw new NotImplementedException ("ACL is not supported in Mono");
+               }
+
+               [MonoNotSupported ("ACL is not supported in Mono")]
+               public void RemoveAuditRuleAll (PipeAuditRule rule)
+               {
+                       throw new NotImplementedException ("ACL is not supported in Mono");
+               }
+
+               [MonoNotSupported ("ACL is not supported in Mono")]
+               public void RemoveAuditRuleSpecific (PipeAuditRule rule)
+               {
+                       throw new NotImplementedException ("ACL is not supported in Mono");
+               }
+
+               [MonoNotSupported ("ACL is not supported in Mono")]
+               public void ResetAccessRule (PipeAccessRule rule)
+               {
+                       throw new NotImplementedException ("ACL is not supported in Mono");
+               }
+
+               [MonoNotSupported ("ACL is not supported in Mono")]
+               public void SetAccessRule (PipeAccessRule rule)
+               {
+                       throw new NotImplementedException ("ACL is not supported in Mono");
+               }
+
+               [MonoNotSupported ("ACL is not supported in Mono")]
+               public void SetAuditRule (PipeAuditRule rule)
+               {
+                       throw new NotImplementedException ("ACL is not supported in Mono");
+               }
+       }
+}
diff --git a/mcs/class/System.Core/System.IO.Pipes/PipeStream.cs b/mcs/class/System.Core/System.IO.Pipes/PipeStream.cs
new file mode 100644 (file)
index 0000000..6c51645
--- /dev/null
@@ -0,0 +1,320 @@
+//
+// PipeStream.cs
+//
+// Author:
+//     Atsushi Enomoto <atsushi@ximian.com>
+//
+// Copyright (C) 2009 Novell, Inc.  http://www.novell.com
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+using Microsoft.Win32.SafeHandles;
+using System;
+using System.IO;
+using System.Linq;
+using System.Security.AccessControl;
+using System.Security.Permissions;
+using System.Security.Principal;
+
+namespace System.IO.Pipes
+{
+       [PermissionSet (SecurityAction.InheritanceDemand, Name = "FullTrust")]
+       [HostProtection (SecurityAction.LinkDemand, MayLeakOnAbort = true)]
+       public abstract class PipeStream : Stream
+       {
+               // FIXME: not precise.
+               internal const int DefaultBufferSize = 0x400;
+
+               internal static bool IsWindows {
+                       get { return Win32Marshal.IsWindows; }
+               }
+
+               internal Exception ThrowACLException ()
+               {
+                       return new NotImplementedException ("ACL is not supported in Mono");
+               }
+
+               internal static PipeAccessRights ToAccessRights (PipeDirection direction)
+               {
+                       switch (direction) {
+                       case PipeDirection.In:
+                               return PipeAccessRights.ReadData;
+                       case PipeDirection.Out:
+                               return PipeAccessRights.WriteData;
+                       case PipeDirection.InOut:
+                               return PipeAccessRights.ReadData | PipeAccessRights.WriteData;
+                       default:
+                               throw new ArgumentOutOfRangeException ();
+                       }
+               }
+
+               internal static PipeDirection ToDirection (PipeAccessRights rights)
+               {
+                       bool r = (rights & PipeAccessRights.ReadData) != 0;
+                       bool w = (rights & PipeAccessRights.WriteData) != 0;
+                       if (r) {
+                               if (w)
+                                       return PipeDirection.InOut;
+                               else
+                                       return PipeDirection.In;
+                       } else {
+                               if (w)
+                                       return PipeDirection.Out;
+                               else
+                                       throw new ArgumentOutOfRangeException ();
+                       }
+               }
+
+               protected PipeStream (PipeDirection direction, int bufferSize)
+                       : this (direction, PipeTransmissionMode.Byte, bufferSize)
+               {
+               }
+
+               protected PipeStream (PipeDirection direction, PipeTransmissionMode transmissionMode, int outBufferSize)
+               {
+                       this.direction = direction;
+                       this.transmission_mode = transmissionMode;
+                       read_trans_mode = transmissionMode;
+                       if (outBufferSize <= 0)
+                               throw new ArgumentOutOfRangeException ("bufferSize must be greater than 0");
+                       buffer_size = outBufferSize;
+               }
+
+               PipeDirection direction;
+               PipeTransmissionMode transmission_mode, read_trans_mode;
+               int buffer_size;
+               SafePipeHandle handle;
+               FileStream stream;
+
+               public override bool CanRead {
+                       get { return (direction & PipeDirection.In) != 0; }
+               }
+
+               public override bool CanSeek {
+                       get { return false; }
+               }
+
+               public override bool CanWrite {
+                       get { return (direction & PipeDirection.Out) != 0; }
+               }
+
+               public virtual int InBufferSize {
+                       get { return buffer_size; }
+               }
+
+               public bool IsAsync { get; private set; }
+
+               public bool IsConnected { get; protected set; }
+
+               private Stream Stream {
+                       get {
+                               if (!IsConnected)
+                                       throw new InvalidOperationException ("Pipe is not connected");
+                               if (stream == null)
+                                       stream = new FileStream (handle.DangerousGetHandle (), CanRead ? (CanWrite ? FileAccess.ReadWrite : FileAccess.Read) : FileAccess.Write, true, buffer_size, IsAsync);
+                               return stream;
+                       }
+               }
+
+               protected bool IsHandleExposed { get; private set; }
+
+               [MonoTODO]
+               public bool IsMessageComplete { get; private set; }
+
+               [MonoTODO]
+               public virtual int OutBufferSize {
+                       get { return buffer_size; }
+               }
+
+               public virtual PipeTransmissionMode ReadMode {
+                       get {
+                               CheckPipePropertyOperations ();
+                               return read_trans_mode;
+                       }
+                       set {
+                               CheckPipePropertyOperations ();
+                               read_trans_mode = value;
+                       }
+               }
+
+               public SafePipeHandle SafePipeHandle {
+                       get {
+                               CheckPipePropertyOperations ();
+                               return handle;
+                       }
+               }
+
+               public virtual PipeTransmissionMode TransmissionMode {
+                       get {
+                               CheckPipePropertyOperations ();
+                               return transmission_mode;
+                       }
+               }
+
+               // initialize/dispose/state check
+
+               [MonoTODO]
+               protected internal virtual void CheckPipePropertyOperations ()
+               {
+               }
+
+               [MonoTODO]
+               protected internal void CheckReadOperations ()
+               {
+                       if (!IsConnected)
+                               throw new InvalidOperationException ("Pipe is not connected");
+                       if (!CanRead)
+                               throw new NotSupportedException ("The pipe stream does not support read operations");
+               }
+
+               [MonoTODO]
+               protected internal void CheckWriteOperations ()
+               {
+                       if (!IsConnected)
+                               throw new InvalidOperationException ("Pipe us not connected");
+                       if (!CanWrite)
+                               throw new NotSupportedException ("The pipe stream does not support write operations");
+               }
+
+               protected void InitializeHandle (SafePipeHandle handle, bool isExposed, bool isAsync)
+               {
+                       this.handle = handle;
+                       this.IsHandleExposed = isExposed;
+                       this.IsAsync = isAsync;
+               }
+
+               protected override void Dispose (bool disposing)
+               {
+                       if (handle != null && disposing)
+                               handle.Dispose ();
+               }
+
+               // not supported
+
+               public override long Length {
+                       get { throw new NotSupportedException (); }
+               }
+
+               public override long Position {
+                       get { return 0; }
+                       set { throw new NotSupportedException (); }
+               }
+
+               public override void SetLength (long value)
+               {
+                       throw new NotSupportedException ();
+               }
+
+               public override long Seek (long offset, SeekOrigin origin)
+               {
+                       throw new NotSupportedException ();
+               }
+
+               [MonoNotSupported ("ACL is not supported in Mono")]
+               public PipeSecurity GetAccessControl ()
+               {
+                       throw ThrowACLException ();
+               }
+
+               [MonoNotSupported ("ACL is not supported in Mono")]
+               public void SetAccessControl (PipeSecurity pipeSecurity)
+               {
+                       throw ThrowACLException ();
+               }
+
+               // pipe I/O
+
+               public void WaitForPipeDrain ()
+               {
+               }
+
+               [MonoTODO]
+               public override int Read (byte [] buffer, int offset, int count)
+               {
+                       CheckReadOperations ();
+
+                       return Stream.Read (buffer, offset, count);
+               }
+
+               [MonoTODO]
+               public override int ReadByte ()
+               {
+                       CheckReadOperations ();
+
+                       return Stream.ReadByte ();
+               }
+
+               [MonoTODO]
+               public override void Write (byte [] buffer, int offset, int count)
+               {
+                       CheckWriteOperations ();
+
+                       Stream.Write (buffer, offset, count);
+               }
+
+               [MonoTODO]
+               public override void WriteByte (byte value)
+               {
+                       CheckWriteOperations ();
+
+                       Stream.WriteByte (value);
+               }
+
+               [MonoTODO]
+               public override void Flush ()
+               {
+                       CheckWriteOperations ();
+
+                       Stream.Flush ();
+               }
+
+               // async
+
+               Func<byte [],int,int,int> read_delegate;
+
+               [HostProtection (SecurityAction.LinkDemand, ExternalThreading = true)]
+               public override IAsyncResult BeginRead (byte [] buffer, int offset, int count, AsyncCallback callback, object state)
+               {
+                       if (read_delegate == null)
+                               read_delegate = new Func<byte[],int,int,int> (Read);
+                       return read_delegate.BeginInvoke (buffer, offset, count, callback, state);
+               }
+
+               Action<byte[],int,int> write_delegate;
+
+               [HostProtection (SecurityAction.LinkDemand, ExternalThreading = true)]
+               public override IAsyncResult BeginWrite (byte[] buffer, int offset, int count, AsyncCallback callback, object state)
+               {
+                       if (write_delegate == null)
+                               write_delegate = new Action<byte[],int,int> (Write);
+                       return write_delegate.BeginInvoke (buffer, offset, count, callback, state);
+               }
+
+               public override int EndRead (IAsyncResult asyncResult)
+               {
+                       return read_delegate.EndInvoke (asyncResult);
+               }
+
+               public override void EndWrite (IAsyncResult asyncResult)
+               {
+                       write_delegate.EndInvoke (asyncResult);
+               }
+       }
+}
diff --git a/mcs/class/System.Core/System.IO.Pipes/PipeStreamImpersonationWorker.cs b/mcs/class/System.Core/System.IO.Pipes/PipeStreamImpersonationWorker.cs
new file mode 100644 (file)
index 0000000..c1b93c7
--- /dev/null
@@ -0,0 +1,4 @@
+namespace System.IO.Pipes
+{
+       public delegate void PipeStreamImpersonationWorker ();
+}
diff --git a/mcs/class/System.Core/System.IO.Pipes/PipeTransmissionMode.cs b/mcs/class/System.Core/System.IO.Pipes/PipeTransmissionMode.cs
new file mode 100644 (file)
index 0000000..2e6c6e3
--- /dev/null
@@ -0,0 +1,9 @@
+namespace System.IO.Pipes
+{
+       [Serializable]
+       public enum PipeTransmissionMode
+       {
+               Byte,
+               Message
+       }
+}
diff --git a/mcs/class/System.Core/System.IO.Pipes/PipeUnix.cs b/mcs/class/System.Core/System.IO.Pipes/PipeUnix.cs
new file mode 100644 (file)
index 0000000..2956786
--- /dev/null
@@ -0,0 +1,194 @@
+//
+// PipeUnix.cs
+//
+// Author:
+//     Atsushi Enomoto <atsushi@ximian.com>
+//
+// Copyright (C) 2009 Novell, Inc.  http://www.novell.com
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+using System;
+using System.ComponentModel;
+using System.IO;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Security.AccessControl;
+using System.Security.Permissions;
+using System.Security.Principal;
+using System.Text;
+using Microsoft.Win32;
+using Microsoft.Win32.SafeHandles;
+
+namespace System.IO.Pipes
+{
+       abstract class UnixAnonymousPipe : IPipe
+       {
+               protected UnixAnonymousPipe ()
+               {
+               }
+
+               public abstract SafePipeHandle Handle { get; }
+
+               public void WaitForPipeDrain ()
+               {
+                       throw new NotImplementedException ();
+               }
+       }
+
+       class UnixAnonymousPipeClient : UnixAnonymousPipe, IAnonymousPipeClient
+       {
+               // AnonymousPipeClientStream owner;
+
+               public UnixAnonymousPipeClient (AnonymousPipeClientStream owner, SafePipeHandle handle)
+               {
+                       // this.owner = owner;
+
+                       this.handle = handle;
+               }
+
+               SafePipeHandle handle;
+
+               public override SafePipeHandle Handle {
+                       get { return handle; }
+               }
+       }
+
+       class UnixAnonymousPipeServer : UnixAnonymousPipe, IAnonymousPipeServer
+       {
+               // AnonymousPipeServerStream owner;
+
+               public UnixAnonymousPipeServer (AnonymousPipeServerStream owner, PipeDirection direction, HandleInheritability inheritability, int bufferSize)
+               {
+                       // this.owner = owner;
+
+                       throw new NotImplementedException ();
+               }
+
+               public UnixAnonymousPipeServer (AnonymousPipeServerStream owner, SafePipeHandle serverHandle, SafePipeHandle clientHandle)
+               {
+                       // this.owner = owner;
+
+                       this.server_handle = serverHandle;
+                       this.client_handle = clientHandle;
+
+                       throw new NotImplementedException ();
+               }
+
+               SafePipeHandle server_handle, client_handle;
+
+               public override SafePipeHandle Handle {
+                       get { return server_handle; }
+               }
+
+               public SafePipeHandle ClientHandle {
+                       get { return client_handle; }
+               }
+
+               public void DisposeLocalCopyOfClientHandle ()
+               {
+                       throw new NotImplementedException ();
+               }
+       }
+
+       abstract class UnixNamedPipe : IPipe
+       {
+               public abstract SafePipeHandle Handle { get; }
+
+               public void WaitForPipeDrain ()
+               {
+                       throw new NotImplementedException ();
+               }
+       }
+
+       class UnixNamedPipeClient : UnixNamedPipe, INamedPipeClient
+       {
+               // .ctor with existing handle
+               public UnixNamedPipeClient (NamedPipeClientStream owner, SafePipeHandle safePipeHandle)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               // .ctor without handle - create new
+               public UnixNamedPipeClient (NamedPipeClientStream owner, string serverName, string pipeName, PipeAccessRights desiredAccessRights, PipeOptions options, HandleInheritability inheritability)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               bool is_async;
+               SafePipeHandle handle;
+
+               public override SafePipeHandle Handle {
+                       get { return handle; }
+               }
+
+               public void Connect ()
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public void Connect (int timeout)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public bool IsAsync {
+                       get { return is_async; }
+               }
+
+               public int NumberOfServerInstances {
+                       get { throw new NotImplementedException (); }
+               }
+       }
+
+       class UnixNamedPipeServer : UnixNamedPipe, INamedPipeServer
+       {
+               //NamedPipeServerStream owner;
+
+               // .ctor with existing handle
+               public UnixNamedPipeServer (NamedPipeServerStream owner, SafePipeHandle safePipeHandle)
+               {
+                       this.handle = safePipeHandle;
+                       //this.owner = owner;
+               }
+
+               // .ctor without handle - create new
+               public UnixNamedPipeServer (NamedPipeServerStream owner, string pipeName, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeAccessRights rights, PipeOptions options, int inBufferSize, int outBufferSize, HandleInheritability inheritability)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               SafePipeHandle handle;
+
+               public override SafePipeHandle Handle {
+                       get { return handle; }
+               }
+
+               public void Disconnect ()
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public void WaitForConnection ()
+               {
+                       throw new NotImplementedException ();
+               }
+       }
+}
diff --git a/mcs/class/System.Core/System.IO.Pipes/PipeWin32.cs b/mcs/class/System.Core/System.IO.Pipes/PipeWin32.cs
new file mode 100644 (file)
index 0000000..9139fa2
--- /dev/null
@@ -0,0 +1,342 @@
+//
+// PipeWin32.cs
+//
+// Author:
+//     Atsushi Enomoto <atsushi@ximian.com>
+//
+// Copyright (C) 2009 Novell, Inc.  http://www.novell.com
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+using System;
+using System.ComponentModel;
+using System.IO;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Security.AccessControl;
+using System.Security.Permissions;
+using System.Security.Principal;
+using System.Text;
+using Microsoft.Win32;
+using Microsoft.Win32.SafeHandles;
+
+namespace System.IO.Pipes
+{
+       abstract class Win32AnonymousPipe : IPipe
+       {
+               protected Win32AnonymousPipe ()
+               {
+               }
+
+               public abstract SafePipeHandle Handle { get; }
+
+               public void WaitForPipeDrain ()
+               {
+                       throw new NotImplementedException ();
+               }
+       }
+
+       class Win32AnonymousPipeClient : Win32AnonymousPipe, IAnonymousPipeClient
+       {
+               // AnonymousPipeClientStream owner;
+
+               public Win32AnonymousPipeClient (AnonymousPipeClientStream owner, SafePipeHandle handle)
+               {
+                       // this.owner = owner;
+
+                       this.handle = handle;
+               }
+
+               SafePipeHandle handle;
+
+               public override SafePipeHandle Handle {
+                       get { return handle; }
+               }
+       }
+
+       class Win32AnonymousPipeServer : Win32AnonymousPipe, IAnonymousPipeServer
+       {
+               // AnonymousPipeServerStream owner;
+
+               public Win32AnonymousPipeServer (AnonymousPipeServerStream owner, PipeDirection direction, HandleInheritability inheritability, int bufferSize)
+               {
+                       IntPtr r, w;
+                       SecurityAttributesHack att = new SecurityAttributesHack (inheritability == HandleInheritability.Inheritable);
+                       if (!Win32Marshal.CreatePipe (out r, out w, ref att, bufferSize))
+                               throw new Win32Exception (Marshal.GetLastWin32Error ());
+
+                       var rh = new SafePipeHandle (r, true);
+                       var wh = new SafePipeHandle (w, true);
+
+                       if (direction == PipeDirection.Out) {
+                               server_handle = wh;
+                               client_handle = rh;
+                       } else {
+                               server_handle = rh;
+                               client_handle = wh;
+                       }
+               }
+
+               public Win32AnonymousPipeServer (AnonymousPipeServerStream owner, SafePipeHandle serverHandle, SafePipeHandle clientHandle)
+               {
+                       // this.owner = owner;
+                       this.server_handle = serverHandle;
+                       this.client_handle = clientHandle;
+               }
+
+               SafePipeHandle server_handle, client_handle;
+
+               public override SafePipeHandle Handle {
+                       get { return server_handle; }
+               }
+
+               public SafePipeHandle ClientHandle {
+                       get { return client_handle; }
+               }
+
+               public void DisposeLocalCopyOfClientHandle ()
+               {
+                       throw new NotImplementedException ();
+               }
+       }
+
+       abstract class Win32NamedPipe : IPipe
+       {
+               string name_cache;
+
+               public string Name {
+                       get {
+                               if (name_cache != null)
+                                       return name_cache;
+
+                               int s, c, m, t;
+                               byte [] un = new byte [200];
+                               while (true) {
+                                       if (!Win32Marshal.GetNamedPipeHandleState (Handle, out s, out c, out m, out t, un, un.Length)) {
+                                               var xxx = Marshal.GetLastWin32Error ();
+                                               throw new Win32Exception (xxx);
+                                       }
+                                       if (un [un.Length - 1] == 0)
+                                               break;
+                                       un = new byte [un.Length * 10];
+                               }
+                               name_cache = Encoding.Default.GetString (un);
+                               return name_cache;
+                       }
+               }
+
+               public abstract SafePipeHandle Handle { get; }
+
+               public void WaitForPipeDrain ()
+               {
+                       throw new NotImplementedException ();
+               }
+       }
+
+       class Win32NamedPipeClient : Win32NamedPipe, INamedPipeClient
+       {
+               NamedPipeClientStream owner;
+
+               // .ctor with existing handle
+               public Win32NamedPipeClient (NamedPipeClientStream owner, SafePipeHandle safePipeHandle)
+               {
+                       this.handle = safePipeHandle;
+                       this.owner = owner;
+
+                       // FIXME: retrieve is_async from state?
+               }
+
+               // .ctor without handle - create new
+               public Win32NamedPipeClient (NamedPipeClientStream owner, string serverName, string pipeName, PipeAccessRights desiredAccessRights, PipeOptions options, HandleInheritability inheritability)
+               {
+                       name = String.Format ("\\\\{0}\\pipe\\{1}", serverName, pipeName);
+                       var att = new SecurityAttributesHack (inheritability == HandleInheritability.Inheritable);
+                       is_async = (options & PipeOptions.Asynchronous) != PipeOptions.None;
+
+                       opener = delegate {
+                               var ret = Win32Marshal.CreateFile (name, desiredAccessRights, 0, ref att, 3, 0, IntPtr.Zero);
+                               if (ret == new IntPtr (-1L))
+                                       throw new Win32Exception (Marshal.GetLastWin32Error ());
+
+                               return new SafePipeHandle (ret, true);
+                       };
+                       this.owner = owner;
+               }
+
+               Func<SafePipeHandle> opener;
+               bool is_async;
+               string name;
+               SafePipeHandle handle;
+
+               public override SafePipeHandle Handle {
+                       get { return handle; }
+               }
+
+               public bool IsAsync {
+                       get { return is_async; }
+               }
+
+               public void Connect ()
+               {
+                       if (owner.IsConnected)
+                               throw new InvalidOperationException ("The named pipe is already connected");
+
+                       handle = opener ();
+               }
+
+               public void Connect (int timeout)
+               {
+                       if (owner.IsConnected)
+                               throw new InvalidOperationException ("The named pipe is already connected");
+
+                       if (!Win32Marshal.WaitNamedPipe (name, timeout))
+                               throw new Win32Exception (Marshal.GetLastWin32Error ());
+                       Connect ();
+               }
+
+               public int NumberOfServerInstances {
+                       get {
+                               int s, c, m, t;
+                               byte [] un = null;
+                               if (!Win32Marshal.GetNamedPipeHandleState (Handle, out s, out c, out m, out t, un, 0))
+                                       throw new Win32Exception (Marshal.GetLastWin32Error ());
+                               return c;
+                       }
+               }
+       }
+
+       class Win32NamedPipeServer : Win32NamedPipe, INamedPipeServer
+       {
+               //NamedPipeServerStream owner;
+
+               // .ctor with existing handle
+               public Win32NamedPipeServer (NamedPipeServerStream owner, SafePipeHandle safePipeHandle)
+               {
+                       handle = safePipeHandle;
+                       //this.owner = owner;
+               }
+
+               // .ctor without handle - create new
+               public Win32NamedPipeServer (NamedPipeServerStream owner, string pipeName, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeAccessRights rights, PipeOptions options, int inBufferSize, int outBufferSize, HandleInheritability inheritability)
+               {
+                       string name = String.Format ("\\\\.\\pipe\\{0}", pipeName);
+
+                       uint openMode = 0;
+                       if ((rights & PipeAccessRights.ReadData) != 0)
+                               openMode |= 1;
+                       if ((rights & PipeAccessRights.WriteData) != 0)
+                               openMode |= 2;
+                       if ((options & PipeOptions.WriteThrough) != 0)
+                               openMode |= 0x80000000;
+                       int pipeMode = 0;
+                       if ((owner.TransmissionMode & PipeTransmissionMode.Message) != 0)
+                               pipeMode |= 4;
+                       //if ((readTransmissionMode & PipeTransmissionMode.Message) != 0)
+                       //      pipeMode |= 2;
+                       if ((options & PipeOptions.Asynchronous) != 0)
+                               pipeMode |= 1;
+
+                       // FIXME: is nDefaultTimeout = 0 ok?
+                       var att = new SecurityAttributesHack (inheritability == HandleInheritability.Inheritable);
+                       var ret = Win32Marshal.CreateNamedPipe (name, openMode, pipeMode, maxNumberOfServerInstances, outBufferSize, inBufferSize, 0, ref att, IntPtr.Zero);
+                       if (ret == new IntPtr (-1L))
+                               throw new Win32Exception (Marshal.GetLastWin32Error ());
+                       handle = new SafePipeHandle (ret, true);
+               }
+
+               SafePipeHandle handle;
+
+               public override SafePipeHandle Handle {
+                       get { return handle; }
+               }
+
+               public void Disconnect ()
+               {
+                       Win32Marshal.DisconnectNamedPipe (Handle);
+               }
+
+               public void WaitForConnection ()
+               {
+                       if (!Win32Marshal.ConnectNamedPipe (Handle, IntPtr.Zero))
+                               throw new Win32Exception (Marshal.GetLastWin32Error ());
+               }
+       }
+
+       [StructLayout (LayoutKind.Sequential)]
+       struct SecurityAttributesHack
+       {
+               public readonly int Length;
+               public readonly IntPtr SecurityDescriptor;
+               public readonly bool Inheritable;
+
+               public SecurityAttributesHack (bool inheritable)
+               {
+                       Length = 0;
+                       SecurityDescriptor = IntPtr.Zero;
+                       Inheritable = inheritable;
+               }
+       }
+
+       static class Win32Marshal
+       {
+               internal static bool IsWindows {
+                       get {
+                               switch (Environment.OSVersion.Platform) {
+                               case PlatformID.Win32S:
+                               case PlatformID.Win32Windows:
+                               case PlatformID.Win32NT:
+                               case PlatformID.WinCE:
+                                       return true;
+                               default:
+                                       return false;
+                               }
+                       }
+               }
+
+               // http://msdn.microsoft.com/en-us/library/aa365152%28VS.85%29.aspx
+               [DllImport ("kernel32")]
+               internal static extern bool CreatePipe (out IntPtr readHandle, out IntPtr writeHandle, ref SecurityAttributesHack pipeAtts, int size);
+
+               // http://msdn.microsoft.com/en-us/library/aa365150%28VS.85%29.aspx
+               [DllImport ("kernel32")]
+               internal static extern IntPtr CreateNamedPipe (string name, uint openMode, int pipeMode, int maxInstances, int outBufferSize, int inBufferSize, int defaultTimeout, ref SecurityAttributesHack securityAttributes, IntPtr atts);
+
+               // http://msdn.microsoft.com/en-us/library/aa365146%28VS.85%29.aspx
+               [DllImport ("kernel32")]
+               internal static extern bool ConnectNamedPipe (SafePipeHandle handle, IntPtr overlapped);
+
+               // http://msdn.microsoft.com/en-us/library/aa365166%28VS.85%29.aspx
+               [DllImport ("kernel32")]
+               internal static extern bool DisconnectNamedPipe (SafePipeHandle handle);
+
+               // http://msdn.microsoft.com/en-us/library/aa365443%28VS.85%29.aspx
+               [DllImport ("kernel32")]
+               internal static extern bool GetNamedPipeHandleState (SafePipeHandle handle, out int state, out int curInstances, out int maxCollectionCount, out int collectDateTimeout, byte [] userName, int maxUserNameSize);
+
+               // http://msdn.microsoft.com/en-us/library/aa365800%28VS.85%29.aspx
+               [DllImport ("kernel32")]
+               internal static extern bool WaitNamedPipe (string name, int timeout);
+
+               // http://msdn.microsoft.com/en-us/library/aa363858%28VS.85%29.aspx
+               [DllImport ("kernel32")]
+               internal static extern IntPtr CreateFile (string name, PipeAccessRights desiredAccess, FileShare fileShare, ref SecurityAttributesHack atts, int creationDisposition, int flags, IntPtr templateHandle);
+
+       }
+}
diff --git a/mcs/class/System.Core/System.IO/ChangeLog b/mcs/class/System.Core/System.IO/ChangeLog
new file mode 100755 (executable)
index 0000000..156af9a
--- /dev/null
@@ -0,0 +1,3 @@
+2009-08-18  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * HandleInheritability.cs : initial code.
diff --git a/mcs/class/System.Core/System.IO/HandleInheritability.cs b/mcs/class/System.Core/System.IO/HandleInheritability.cs
new file mode 100644 (file)
index 0000000..df3f355
--- /dev/null
@@ -0,0 +1,8 @@
+namespace System.IO
+{
+       public enum HandleInheritability
+       {
+               None,
+               Inheritable
+       }
+}
index 0fdb0e2357de3d73742d2b6ba9d717fcf2ddd539..40c30b02f918ef79be15407bec2a03ce7887787b 100644 (file)
@@ -1,3 +1,8 @@
+2009-08-17  Veerapuram Varadhan  <vvaradhan@novell.com>
+
+       * System.Data_test.dll.sources: Added
+       Mono.Data.SqlExpressions/DateComparisonTest.cs.
+       
 2009-07-15  Veerapuram Varadhan  <vvaradhan@novell.com>
 
        * System.Data.dll.sources: Added TableAdapterSchemaInfo.cs.
index 215156e273c02cecdbf1208ac7d169a03031f232..c3663627b58252c7424fe8c45df0b56303134b1d 100644 (file)
@@ -1,3 +1,8 @@
+2009-07-23  Adam Wendt  <adam@awendtconsulting.com>
+
+       * Comparison.cs (Compare): Parse string if other object is DateTime
+       regardless of which side the DateTime is on.
+
 2008-08-18  Marek Habersack  <mhabersack@novell.com>
 
        * Numeric.cs: Max/Min operations do not convert string
index 3ab90c13695280424bfb68b5548f1920ed226090..9049205eee8a7e3235819e3f3d0c1bfee11c027b 100644 (file)
@@ -100,6 +100,10 @@ namespace Mono.Data.SqlExpressions {
                        if (o1 is DateTime && o2 is string && Thread.CurrentThread.CurrentCulture != CultureInfo.InvariantCulture) {
                                // DateTime is always CultureInfo.InvariantCulture
                                o2 = (IComparable) DateTime.Parse ((string)o2, CultureInfo.InvariantCulture);
+                       } else if (o2 is DateTime && o1 is string && 
+                                  Thread.CurrentThread.CurrentCulture != CultureInfo.InvariantCulture) {
+                               // DateTime is always CultureInfo.InvariantCulture
+                o1 = (IComparable) DateTime.Parse ((string)o1, CultureInfo.InvariantCulture);
                        }
 
                        if (o1.GetType () != o2.GetType ())
index a51545b66781312737269476c43263405554f2d1..583f66c59c44c8b6becd454e06f72216e68110f7 100644 (file)
@@ -1,3 +1,9 @@
+2009-08-17  Veerapuram Varadhan  <vvaradhan@novell.com>
+
+       ** Fixes #525306
+       * SqlConnection.cs (Open): Use Tds80 also in case of non-pooling 
+       connections.
+
 2009-08-01  Gert Driesen  <drieseng@users.sourceforge.net>
 
        * SqlParameter.cs (ConvertToFrameworkType): Only wrap FormatException
index c28cb8a16fcd14fe84e5c448dca5d3f9f64502e7..41bcf232570d50aacecd558e7c02a56d345c630a 100644 (file)
@@ -535,7 +535,7 @@ namespace System.Data.SqlClient
                                if (!pooling) {
                                        if(!ParseDataSource (dataSource, out port, out serverName))
                                                throw new SqlException(20, 0, "SQL Server does not exist or access denied.",  17, "ConnectionOpen (Connect()).", dataSource, parms.ApplicationName, 0);
-                                       tds = new Tds70 (serverName, port, PacketSize, ConnectionTimeout);
+                                       tds = new Tds80 (serverName, port, PacketSize, ConnectionTimeout);
                                        tds.Pooling = false;
                                }
                                else {
index 1c106e051f1b162805080e52b0112e547faf31b2..5ce579ff80987415655570b9bdfafcd362c58ef6 100644 (file)
@@ -121,3 +121,5 @@ System.Data.SqlClient/SqlClientPermissionTest.cs
 System.Data.SqlClient/SqlDataAdapterTest.cs
 System.Data.SqlClient/SqlParameterTest.cs
 Mono.Data.SqlExpressions/DataColumnExpressionTest.cs
+Mono.Data.SqlExpressions/DateComparisonTest.cs
+
index c72b837dd18248ec2a393a398d66185966246923..92268dc93d2cf1aeb5cdd25a940f27c84ed1982f 100644 (file)
@@ -1,3 +1,14 @@
+2009-08-18  Veerapuram Varadhan  <vvaradhan@novell.com>
+
+       * DateComparisonTest.cs: Fix test-data xml path.
+       
+2009-07-23  Adam Wendt  <adam@awendtconsulting.com>
+
+       * DateComparisonTest.cs
+       (TestDateComparisonRight, TestDateComparisonLeft): Test case to
+       check that comparison of date and string works regardless of which
+       side the existing date is.
+
 2007-06-06  Nagappan A  <anagappan@novell.com>
 
        * DataColumnExpressionTest.cs (DataColumnCharTest): Test case to
diff --git a/mcs/class/System.Data/Test/Mono.Data.SqlExpressions/DateComparisonTest.cs b/mcs/class/System.Data/Test/Mono.Data.SqlExpressions/DateComparisonTest.cs
new file mode 100644 (file)
index 0000000..cf38d8b
--- /dev/null
@@ -0,0 +1,34 @@
+using System;
+using System.Data;
+using NUnit.Framework;
+
+namespace Monotests_Mono.Data.SqlExpressions
+{
+       [TestFixture]   
+       public class DateComparisonTest
+       {
+               private DataSet dataSet;
+
+               [SetUp]
+               public void SetUp()
+               {
+                       dataSet = new DataSet();
+                       dataSet.ReadXml("Test/Mono.Data.SqlExpressions/dateComparisonTest.xml", 
+                                      XmlReadMode.InferSchema);
+               }
+
+               [Test]
+               public void TestDateComparisonRight()
+               {
+                       DataView dataView = new DataView(dataSet.Tables["thing"], "#2009-07-19 00:01:00# = start", "", DataViewRowState.CurrentRows);
+                       Assert.AreEqual (1, dataView.Count);
+               }
+               
+               [Test]
+               public void TestDateComparisonLeft()
+               {
+                       DataView dataView = new DataView(dataSet.Tables["thing"], "start = #2009-07-19 00:01:00#", "", DataViewRowState.CurrentRows);
+                       Assert.AreEqual (1, dataView.Count);
+               }
+       }
+}
diff --git a/mcs/class/System.Data/Test/Mono.Data.SqlExpressions/dateComparisonTest.xml b/mcs/class/System.Data/Test/Mono.Data.SqlExpressions/dateComparisonTest.xml
new file mode 100644 (file)
index 0000000..265b93d
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8" ?> 
+<things>
+<thing>
+    <title>bar</title>
+    <start>2009-07-19 00:01</start>
+</thing>
+<thing>
+    <title>foo</title>
+    <start>2009-08-19 00:01</start>
+</thing>
+</things>
index ecfc9a6056bc6bf9639e83c4d393b3e437bd4c52..b87e10a4f990a6819424614b2ff505c07c0c2d67 100644 (file)
@@ -1,3 +1,8 @@
+2009-08-11  Gert Driesen  <drieseng@users.sourceforge.net>
+
+       * sqlserver7.sql: Added script for SQL Server 7.0, with unicode
+       encoding (as isql7 does not deal well with utf-8).
+
 2008-12-31  Gert Driesen  <drieseng@users.sourceforge.net>
 
        * MySQL_5.sql: Added numeric and decimal colums with different
diff --git a/mcs/class/System.Data/Test/ProviderTests/sql/sqlserver7.sql b/mcs/class/System.Data/Test/ProviderTests/sql/sqlserver7.sql
new file mode 100644 (file)
index 0000000..a7ad3e7
Binary files /dev/null and b/mcs/class/System.Data/Test/ProviderTests/sql/sqlserver7.sql differ
index 9b7630ac3bdda5d57cad5fcd26b6e64d4696f716..44919b9bb373f5e94563d682882fe18bff166262 100644 (file)
@@ -1,3 +1,7 @@
+2009-08-13  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * Makefile : update profile check.
+
 2008-06-10  Atsushi Enomoto  <atsushi@ximian.com>
 
        * System.Json.dll.sources, Makefile : initial checkin.
index 5348b3a87052add4fcd66702a92fce8c4fa657f7..52f4f7d0cf35a6e902c4a4685e76c1e38f940e0b 100644 (file)
@@ -11,7 +11,8 @@ TEST_MCS_FLAGS = $(LIB_MCS_FLAGS)
 
 EXTRA_DISTFILES =
 
-ifneq (net_2_1, $(PROFILE))
+VALID_PROFILE := $(filter 2.1 4.0, $(FRAMEWORK_VERSION))
+ifndef VALID_PROFILE
 LIBRARY_NAME = dummy-System.Json.dll
 NO_INSTALL = yes
 NO_SIGN_ASSEMBLY = yes
index 1d999d040c98d4e9f1cfa0707e23629f9cec4a0a..e62c161105b318cfbc4ec9b9a577b721336ad239 100644 (file)
@@ -1,3 +1,8 @@
+2009-08-17  Sebastien Pouliot  <sebastien@ximian.com>
+
+       * net_2_1_raw_System.Net.dll.sources: Add some existing System.dll
+       files required for SL3 and some new files.
+
 2009-07-20  Jb Evain  <jbevain@novell.com>
 
        * Makefile: filter the valid profile on the framework version,
diff --git a/mcs/class/System.Net/System.Net.NetworkInformation/ChangeLog b/mcs/class/System.Net/System.Net.NetworkInformation/ChangeLog
new file mode 100644 (file)
index 0000000..c341730
--- /dev/null
@@ -0,0 +1,5 @@
+2009-08-17  Sebastien Pouliot  <sebastien@ximian.com>
+
+       * NetworkChange_2_1.cs: New. Minimal SL3 version
+       * NetworkInterface_2_1.cs: New. Minimal SL3 version
+
diff --git a/mcs/class/System.Net/System.Net.NetworkInformation/NetworkChange_2_1.cs b/mcs/class/System.Net/System.Net.NetworkInformation/NetworkChange_2_1.cs
new file mode 100644 (file)
index 0000000..a06941c
--- /dev/null
@@ -0,0 +1,42 @@
+//
+// System.Net.NetworkInformation.NetworkChange
+//
+// Author:
+//     Gonzalo Paniagua Javier (gonzalo@novell.com)
+//
+// Copyright (c) 2006, 2009 Novell, Inc. (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+#if NET_2_1
+namespace System.Net.NetworkInformation {
+       public abstract class NetworkChange {
+               protected NetworkChange ()
+               {
+               }
+
+               // Disable the warnings about the events not being used.
+#pragma warning disable 67
+               public static event NetworkAddressChangedEventHandler NetworkAddressChanged;
+#pragma warning restore
+       }
+}
+#endif
+
diff --git a/mcs/class/System.Net/System.Net.NetworkInformation/NetworkInterface_2_1.cs b/mcs/class/System.Net/System.Net.NetworkInformation/NetworkInterface_2_1.cs
new file mode 100644 (file)
index 0000000..4112ea8
--- /dev/null
@@ -0,0 +1,52 @@
+//
+// System.Net.NetworkInformation.NetworkInterface
+//
+// Authors:
+//     Gonzalo Paniagua Javier (gonzalo@novell.com)
+//     Atsushi Enomoto (atsushi@ximian.com)
+//      Miguel de Icaza (miguel@novell.com)
+//      Eric Butler (eric@extremeboredom.net)
+//      Marek Habersack (mhabersack@novell.com)
+//
+// Copyright (c) 2006-2009 Novell, Inc. (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#if NET_2_1
+
+namespace System.Net.NetworkInformation {
+
+       public abstract class NetworkInterface {
+
+               protected NetworkInterface ()
+               {
+               }
+
+               [MonoTODO("Always returns true")]
+               public static bool GetIsNetworkAvailable ()
+               {
+                       return true;
+               }
+       }
+}
+
+#endif
+
index c077ed32560043516ed823df586e305004becc26..ca84632461a65027af27eb1ec8c66df2d2cdd191 100644 (file)
@@ -15,15 +15,23 @@ System.Net.Sockets/SocketException_2_1.cs
 System.Net.Sockets/ProtocolType_2_1.cs
 System.Net.Sockets/SocketAsyncOperation_2_1.cs
 System.Net.Sockets/SocketType_2_1.cs
+System.Net.NetworkInformation/NetworkChange_2_1.cs
+System.Net.NetworkInformation/NetworkInterface_2_1.cs
+../System/System.Net/Cookie.cs
+../System/System.Net/CookieCollection.cs
+../System/System.Net/CookieContainer.cs
+../System/System.Net/CookieException.cs
 ../System/System.Net/Dns.cs
 ../System/System.Net/EndPoint.cs
 ../System/System.Net/HttpRequestHeader.cs
 ../System/System.Net/HttpResponseHeader.cs
+../System/System.Net/ICredentialLookup.cs
 ../System/System.Net/IPAddress.cs
 ../System/System.Net/IPEndPoint.cs
 ../System/System.Net/IPHostEntry.cs
 ../System/System.Net/IPv6Address.cs
 ../System/System.Net/IWebRequestCreate.cs
+../System/System.Net/NetworkCredential.cs
 ../System/System.Net/ProtocolViolationException.cs
 ../System/System.Net/SocketAddress.cs
 ../System/System.Net.Sockets/LingerOption.cs
@@ -50,3 +58,4 @@ System.Net.Sockets/SocketType_2_1.cs
 ../System/System.Net/UploadProgressChangedEventHandler.cs
 ../System/System.Net/UploadStringCompletedEventArgs.cs
 ../System/System.Net/UploadStringCompletedEventHandler.cs
+../System/System.Net.NetworkInformation/NetworkAddressChangedEventHandler.cs
index 0ed9b09c3ebf2260bc02d6d41f012e962adf36a0..58558bf33201c9efa171499fd48eb21d11f4826f 100644 (file)
@@ -1,3 +1,7 @@
+2009-08-11  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * WebChannelFactory.cs : added missing constructors.
+
 2009-07-28  Atsushi Enomoto  <atsushi@ximian.com>
 
        * OutgoingWebRequestContext.cs : implement.
index fde26ec255c2e04151bffb5781e7065819b2f1c3..7670649b3fd9e76c6b7b3eef933fe17d6c07243e 100644 (file)
@@ -60,19 +60,18 @@ namespace System.ServiceModel.Web
                }
 
                public WebChannelFactory (Uri remoteAddress)
-                       : base ()
+                       : this (String.Empty, remoteAddress)
                {
-                       Endpoint.Address = new EndpointAddress (remoteAddress);
                }
 
-               public WebChannelFactory (string configurationName, Uri remoteAddress)
-                       : this (configurationName)
+               public WebChannelFactory (string endpointConfigurationName, Uri remoteAddress)
+                       : base (endpointConfigurationName)
                {
                        Endpoint.Address = new EndpointAddress (remoteAddress);
                }
 
                public WebChannelFactory (Binding binding, Uri remoteAddress)
-                       : this (new ServiceEndpoint (ContractDescription.GetContract (typeof (TChannel)), binding, new EndpointAddress (remoteAddress)))
+                       : base (binding, new EndpointAddress (remoteAddress))
                {
                }
 
index 324ec5828fcfed6d6c67775db681d535b4f63971..96c5a2b63c99aa4887509f330c0ced09664af853 100755 (executable)
@@ -1,3 +1,7 @@
+2009-08-11  Astushi Enomoto  <atsushi@ximian.com>
+
+       * System.ServiceModel.dll.sources: add DefaultOperationInvoker.cs.
+
 2009-08-07  Astushi Enomoto  <atsushi@ximian.com>
 
        * System.ServiceModel.dll.sources: add ServiceProxyGenerator.cs.
index 243d1a2ba0854657da30ec7da31b14f717272fe7..7fbcdcebc540a33478a057206f0678bd932c5e59 100644 (file)
@@ -4,7 +4,7 @@
 // Author:
 //     Atsushi Enomoto <atsushi@ximian.com>
 //
-// Copyright (C) 2005 Novell, Inc.  http://www.novell.com
+// Copyright (C) 2005,2009 Novell, Inc.  http://www.novell.com
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -27,6 +27,7 @@
 //
 using System;
 using System.Collections.ObjectModel;
+using System.IO;
 using System.Runtime.Serialization;
 using System.Xml;
 
@@ -56,14 +57,19 @@ namespace System.ServiceModel.Channels
                        OnWriteBodyContents (writer);
                }
 
-               [MonoTODO]
+               [MonoTODO ("use maxBufferSize somewhere")]
                protected virtual BodyWriter OnCreateBufferedCopy (
                        int maxBufferSize)
                {
-                       throw new NotImplementedException ();
+                       var s = new XmlWriterSettings ();
+                       s.OmitXmlDeclaration = true;
+                       s.ConformanceLevel = ConformanceLevel.Auto;
+                       StringWriter sw = new StringWriter ();
+                       using (XmlDictionaryWriter w = XmlDictionaryWriter.CreateDictionaryWriter (XmlWriter.Create (sw, s)))
+                               WriteBodyContents (w);
+                       return new XmlReaderBodyWriter (sw.ToString ());
                }
 
-               [MonoTODO]
                protected abstract void OnWriteBodyContents (
                        XmlDictionaryWriter writer);
        }
index 14baa1af374135e228c281b22aa2bd18d3bf46c5..a3a4fdcc08cd4fb1063b83bce61c1ca9369aaf22 100755 (executable)
@@ -1,3 +1,72 @@
+2009-08-18  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * Message.cs, MessageImpl.cs, BodyWriter.cs :
+         Implement BodyWriter.OnCreateBufferedCopy() and use it.
+
+2009-08-18  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * ReplyChannelBase.cs : initialize field.
+
+2009-08-17  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * ReplyChannelBase.cs, DuplexChannelBase.cs, RequestChannelBase.cs:
+         implement GetProperty<T>() and return its channel manager.
+
+2009-08-17  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * PeerDuplexChannel.cs : ongoing implementation. Fix wrong peer
+         destination address in Connect() request. To repeat sending
+         request, use buffered copy. Set some peer-channel specific
+         header items. (todo: and consume them.)
+
+2009-08-17  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * Message.cs : state is set only after WriteBodyContents().
+
+2009-08-17  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * MessageHeaders.cs : eliminate wrong use of
+         ReadElementContentAsString() (it is not always simple string).
+
+2009-08-17  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * MessageHeaders.cs : when the value is null, do not try to
+         deserialize EndpointAddress.
+
+2009-08-17  Atsushi Enomoto  <atsushi@ximian.com>
+
+        * MessageHeader.cs : add Value property. (Forgot dependent change.)
+
+2009-08-17  Atsushi Enomoto  <atsushi@ximian.com>
+
+        * MessageHeaders.cs : GetHeader<T>() could mostly skip extra
+          serialization and deserialization of values.
+
+2009-08-14  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * PeerDuplexChannel.cs : handle Welcome and Refuse at client side.
+         Now simply use connector contract.
+
+2009-08-14  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * PeerDuplexChannel.cs : handle Disconnect(). Fix URLs a bit.
+
+2009-08-14  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * TcpChannelListener.cs : do not try to compare dead connection's
+         IPEndPoint (it raises an error).
+
+2009-08-14  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * MessageHeaders.cs : allow null header value on each specific setter.
+
+2009-08-14  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * DuplexChannelBase.cs, TcpDuplexSessionChannel.cs :
+         get local and remote address of connected counterpart to get
+         callback channel connected.
+       * PeerDuplexChannel.cs : remove FIXME wrt above.
+
 2009-08-07  Atsushi Enomoto  <atsushi@ximian.com>
 
        * PeerDuplexChannel.cs : add fixme comment and remove extra FIXME.
index 4ef412f886fd644cd1e1ae0cef92c1c82de416c6..75149f816f4a7225d0058f33066084d6b5f762fd 100644 (file)
@@ -36,15 +36,15 @@ namespace System.ServiceModel.Channels
 {
        internal abstract class DuplexChannelBase : ChannelBase, IDuplexChannel
        {
-               //ChannelFactoryBase channel_factory_base;
-               //ChannelListenerBase channel_listener_base;
+               ChannelFactoryBase channel_factory_base;
+               ChannelListenerBase channel_listener_base;
                EndpointAddress local_address;
                EndpointAddress remote_address;
                Uri via;
                
                public DuplexChannelBase (ChannelFactoryBase factory, EndpointAddress remoteAddress, Uri via) : base (factory)
                {
-                       //channel_factory_base = factory;
+                       channel_factory_base = factory;
                        remote_address = remoteAddress;
                        this.via = via;
                        SetupDelegates ();
@@ -52,16 +52,16 @@ namespace System.ServiceModel.Channels
                
                public DuplexChannelBase (ChannelListenerBase listener) : base (listener)
                {
-                       //channel_listener_base = listener;
+                       channel_listener_base = listener;
                        local_address = new EndpointAddress (listener.Uri);
                        SetupDelegates ();
                }
 
-               public EndpointAddress LocalAddress {
+               public virtual EndpointAddress LocalAddress {
                        get { return local_address; }
                }
 
-               public EndpointAddress RemoteAddress {
+               public virtual EndpointAddress RemoteAddress {
                        get { return remote_address; }
                }
 
@@ -79,6 +79,15 @@ namespace System.ServiceModel.Channels
                        try_receive_handler = new TryReceiveHandler (TryReceive);
                }
 
+               public override T GetProperty<T> ()
+               {
+                       if (typeof (T) == typeof (IChannelFactory))
+                               return (T) (object) channel_factory_base;
+                       if (typeof (T) == typeof (IChannelListener))
+                               return (T) (object) channel_listener_base;
+                       return base.GetProperty<T> ();
+               }
+
                // Open
                Action<TimeSpan> open_handler;
 
index 560477221d6d6bf04ed9e1b6dced407661833ad2..2a306e705ae2eaaa2f06a89327af7349b04168bc 100644 (file)
@@ -162,13 +162,13 @@ namespace System.ServiceModel.Channels
                                OnWriteBodyContents (writer);
                        else if (Version.Envelope == EnvelopeVersion.None)
                                WriteXsiNil (writer);
+                       State = MessageState.Written;
                }
 
                public void WriteMessage (XmlDictionaryWriter writer)
                {
                        if (State != MessageState.Created)
                                throw new InvalidOperationException (String.Format ("The message is already at {0} state", State));
-                       State = MessageState.Written;
 
                        OnWriteMessage (writer);
                }
@@ -180,9 +180,8 @@ namespace System.ServiceModel.Channels
 
                public void WriteStartBody (XmlDictionaryWriter writer)
                {
-                       if (State != MessageState.Created && State != MessageState.Written)
+                       if (State != MessageState.Created)
                                throw new InvalidOperationException (String.Format ("The message is already at {0} state", State));
-                       State = MessageState.Written;
 
                        OnWriteStartBody (writer);
                }
@@ -195,9 +194,8 @@ namespace System.ServiceModel.Channels
 
                public void WriteStartEnvelope (XmlDictionaryWriter writer)
                {
-                       if (State != MessageState.Created && State != MessageState.Written)
+                       if (State != MessageState.Created)
                                throw new InvalidOperationException (String.Format ("The message is already at {0} state", State));
-                       State = MessageState.Written;
 
                        OnWriteStartEnvelope (writer);
                }
@@ -213,6 +211,7 @@ namespace System.ServiceModel.Channels
                {
                }
 
+               [MonoTODO ("use maxBufferSize")]
                protected virtual MessageBuffer OnCreateBufferedCopy (
                        int maxBufferSize)
                {
index 89f7948fcf48ab414cae9f2edd72bb259c792fdd..e13a27feb704951a2e7d5371acfa694ecc5cb3a8 100644 (file)
@@ -287,6 +287,8 @@ namespace System.ServiceModel.Channels
                                        this.formatter.WriteObjectContent (writer, value);
                        }
 
+                       public object Value { get { return value; } }
+
                        public override string Actor { get { return actor; }}
 
                        public override bool IsReferenceParameter { get { return is_ref; }}
index 34dde7b58c1befc97de1f32ac7d6df3271b8cfc5..cd00eff07f15fdc0dc58ca82755bf9562691c206 100644 (file)
@@ -157,9 +157,14 @@ namespace System.ServiceModel.Channels
 
                public T GetHeader<T> (int index)
                {
+                       if (l.Count <= index)
+                               throw new ArgumentOutOfRangeException ("index");
+                       var dmh = l [index] as MessageHeader.DefaultMessageHeader;
+                       if (dmh != null && dmh.Value != null && typeof (T).IsAssignableFrom (dmh.Value.GetType ()))
+                               return (T) dmh.Value;
                        if (typeof (T) == typeof (EndpointAddress)) {
                                XmlDictionaryReader r = GetReaderAtHeader (index);
-                               return (T) (object) new EndpointAddress (r.ReadElementContentAsString ());
+                               return r.NodeType != XmlNodeType.Element ? default (T) : (T) (object) EndpointAddress.ReadFrom (r);
                        }
                        else
                                return GetHeader<T> (index, GetSerializer<T> (index));
@@ -318,7 +323,8 @@ namespace System.ServiceModel.Channels
                        }
                        set {
                                RemoveAll ("Action", version.Addressing.Namespace);
-                               Add (MessageHeader.CreateHeader ("Action", version.Addressing.Namespace, value, true));
+                               if (value != null)
+                                       Add (MessageHeader.CreateHeader ("Action", version.Addressing.Namespace, value, true));
                        }
                }
 
@@ -337,10 +343,8 @@ namespace System.ServiceModel.Channels
                                        throw new InvalidOperationException ("WS-Addressing header is not allowed for AddressingVersion.None");
 
                                RemoveAll ("FaultTo", Constants.WSA1);
-                               Add (MessageHeader.CreateHeader (
-                                               "FaultTo", 
-                                               Constants.WSA1,
-                                               EndpointAddress10.FromEndpointAddress (value)));
+                               if (value != null)
+                                       Add (MessageHeader.CreateHeader ("FaultTo", Constants.WSA1, EndpointAddress10.FromEndpointAddress (value)));
                        }
                }
 
@@ -354,10 +358,8 @@ namespace System.ServiceModel.Channels
                                        throw new InvalidOperationException ("WS-Addressing header is not allowed for AddressingVersion.None");
 
                                RemoveAll ("From", Constants.WSA1);
-                               Add (MessageHeader.CreateHeader (
-                                               "From", 
-                                               Constants.WSA1,
-                                               EndpointAddress10.FromEndpointAddress (value)));
+                               if (value != null)
+                                       Add (MessageHeader.CreateHeader ("From", Constants.WSA1, EndpointAddress10.FromEndpointAddress (value)));
                        }
                }
 #endif
@@ -376,10 +378,8 @@ namespace System.ServiceModel.Channels
                                        throw new InvalidOperationException ("WS-Addressing header is not allowed for AddressingVersion.None");
 
                                RemoveAll ("MessageID", Constants.WSA1);
-                               Add (MessageHeader.CreateHeader (
-                                               "MessageID", 
-                                               Constants.WSA1,
-                                               value.ToString ()));
+                               if (value != null)
+                                       Add (MessageHeader.CreateHeader ("MessageID", Constants.WSA1, value.ToString ()));
                        }
                }
 
@@ -395,10 +395,8 @@ namespace System.ServiceModel.Channels
                                        throw new InvalidOperationException ("WS-Addressing header is not allowed for AddressingVersion.None");
 
                                RemoveAll ("MessageID", Constants.WSA1);
-                               Add (MessageHeader.CreateHeader (
-                                               "RelatesTo", 
-                                               Constants.WSA1,
-                                               value.ToString ()));
+                               if (value != null)
+                                       Add (MessageHeader.CreateHeader ("RelatesTo", Constants.WSA1, value.ToString ()));
                        }
 
                }
@@ -414,10 +412,8 @@ namespace System.ServiceModel.Channels
                                        throw new InvalidOperationException ("WS-Addressing header is not allowed for AddressingVersion.None");
 
                                RemoveAll ("ReplyTo", Constants.WSA1);
-                               Add (MessageHeader.CreateHeader (
-                                               "ReplyTo", 
-                                               Constants.WSA1,
-                                               EndpointAddress10.FromEndpointAddress (value)));
+                               if (value != null)
+                                       Add (MessageHeader.CreateHeader ("ReplyTo", Constants.WSA1, EndpointAddress10.FromEndpointAddress (value)));
                        }
                }
 #endif
@@ -430,11 +426,8 @@ namespace System.ServiceModel.Channels
                        }
                        set { 
                                RemoveAll ("To", version.Addressing.Namespace);
-                               Add (MessageHeader.CreateHeader (
-                                               "To", 
-                                               version.Addressing.Namespace, 
-                                               value.AbsoluteUri,
-                                               true));
+                               if (value != null)
+                                       Add (MessageHeader.CreateHeader ("To", version.Addressing.Namespace, value.AbsoluteUri, true));
                        }
                }
 
index a98c718a50795bb7fb0eb891fb405f3ae6eb7403..b3ca10f349156300dbdca0ccb64c10729f4cf900 100644 (file)
@@ -255,6 +255,14 @@ namespace System.ServiceModel.Channels
                {
                        body.WriteBodyContents (writer);
                }
+
+               protected override MessageBuffer OnCreateBufferedCopy (
+                       int maxBufferSize)
+               {
+                       var headers = new MessageHeaders (Headers);
+                       var props = new MessageProperties (Properties);
+                       return new DefaultMessageBuffer (maxBufferSize, headers, props, body.CreateBufferedCopy (maxBufferSize), false);
+               }
        }
 }
 
index 9e47007b27aff00ac6154e86f3060bb9183abd36..0697e262fbb402dd694b0bb79fbc9ecf88400079 100755 (executable)
@@ -37,6 +37,7 @@ using System.ServiceModel.Description;
 using System.ServiceModel.PeerResolvers;
 using System.ServiceModel.Security;
 using System.Threading;
+using System.Xml;
 
 namespace System.ServiceModel.Channels
 {
@@ -69,7 +70,7 @@ namespace System.ServiceModel.Channels
                        public IPeerConnectorClient Channel { get; set; }
                }
 
-               class LocalPeerReceiver : IPeerReceiverContract
+               class LocalPeerReceiver : IPeerConnectorContract
                {
                        public LocalPeerReceiver (PeerDuplexChannel owner)
                        {
@@ -82,27 +83,38 @@ namespace System.ServiceModel.Channels
                        {
                                if (connect == null)
                                        throw new ArgumentNullException ("connect");
-try {
                                var ch = OperationContext.Current.GetCallbackChannel<IPeerConnectorContract> ();
-// FIXME: so, this duplex channel, when created by a listener, lacks RemoteAddress to send callback. Get it from somewhere.
-Console.WriteLine ("FIXME FIXME:" + ((IContextChannel) ch).RemoteAddress);
+                               // FIXME: wrong destination
                                // FIXME: check and reject if inappropriate.
                                ch.Welcome (new WelcomeInfo () { NodeId = connect.NodeId });
+                       }
 
-} catch (Exception ex) {
-Console.WriteLine ("Exception during Connect()");
-Console.WriteLine (ex);
-throw;
-}
-
+                       public void Disconnect (DisconnectInfo disconnect)
+                       {
+                               if (disconnect == null)
+                                       throw new ArgumentNullException ("disconnect");
+                               // Console.WriteLine ("DisconnectInfo.Reason: " + disconnect.Reason);
+                               // FIXME: handle disconnection in practice. So far I see nothing to do.
                        }
 
                        public void Welcome (WelcomeInfo welcome)
                        {
+                               owner.HandleWelcomeResponse (welcome);
                        }
 
                        public void Refuse (RefuseInfo refuse)
                        {
+                               owner.HandleRefuseResponse (refuse);
+                       }
+
+                       public void LinkUtility (LinkUtilityInfo linkUtility)
+                       {
+                               throw new NotImplementedException ();
+                       }
+
+                       public void Ping ()
+                       {
+                               throw new NotImplementedException ();
                        }
 
                        public void SendMessage (Message msg)
@@ -123,6 +135,7 @@ throw;
                ServiceHost listener_host;
                TcpChannelInfo info;
                List<RemotePeerConnection> peers = new List<RemotePeerConnection> ();
+               PeerNodeAddress local_node_address;
 
                public PeerDuplexChannel (IPeerChannelManager factory, EndpointAddress address, Uri via, PeerResolver resolver)
                        : base ((ChannelFactoryBase) factory, address, via)
@@ -164,28 +177,62 @@ throw;
                                channel_factory = new ChannelFactory<IPeerConnectorClient> (binding);
                        }
 
-                       return channel_factory.CreateChannel (new EndpointAddress ("net.p2p://" + node.MeshId), pna.EndpointAddress.Uri);
+                       return channel_factory.CreateChannel (new EndpointAddress ("net.p2p://" + node.MeshId + "/"), pna.EndpointAddress.Uri);
                }
 
+               public void HandleWelcomeResponse (WelcomeInfo welcome)
+               {
+                       last_connect_response = welcome;
+                       connect_handle.Set ();
+               }
+
+               public void HandleRefuseResponse (RefuseInfo refuse)
+               {
+                       last_connect_response = refuse;
+                       connect_handle.Set ();
+               }
+
+               AutoResetEvent connect_handle = new AutoResetEvent (false);
+               object last_connect_response;
+
                public override void Send (Message message, TimeSpan timeout)
                {
                        ThrowIfDisposedOrNotOpen ();
 
                        DateTime start = DateTime.Now;
-                       
+
+                       // FIXME: give max buffer size
+                       var mb = message.CreateBufferedCopy (0x10000);
+
                        foreach (var pc in peers) {
+                               message = mb.CreateMessage ();
+
                                if (pc.Status == RemotePeerStatus.None) {
+                                       pc.Status = RemotePeerStatus.Error; // prepare for cases that it resulted in an error in the middle.
                                        var inner = CreateInnerClient (pc.Address);
                                        pc.Channel = inner;
                                        inner.Open (timeout - (DateTime.Now - start));
                                        inner.OperationTimeout = timeout - (DateTime.Now - start);
-                                       inner.Connect (new ConnectInfo () { PeerNodeAddress = pc.Address, NodeId = (uint) node.NodeId });
+                                       inner.Connect (new ConnectInfo () { Address = local_node_address, NodeId = (uint) node.NodeId });
 
                                        // FIXME: wait for Welcome or Reject and take further action.
-                                       throw new NotImplementedException ();
+/*
+Console.WriteLine ("WAITING FOR Welcome or Refuse");
+                                       if (!connect_handle.WaitOne (timeout - (DateTime.Now - start)))
+                                               throw new TimeoutException ();
+Console.WriteLine ("got signaled");
+                                       if (last_connect_response is RefuseInfo)
+                                               throw new CommunicationException ("Peer neighbor connection was refused");
+*/
+                                       pc.Status = RemotePeerStatus.Connected;
                                }
 
                                pc.Channel.OperationTimeout = timeout - (DateTime.Now - start);
+
+                               if (message.Headers.MessageId == null)
+                                       message.Headers.MessageId = new UniqueId ();
+                               message.Headers.Add (MessageHeader.CreateHeader ("PeerTo", String.Empty, RemoteAddress));
+                               message.Headers.Add (MessageHeader.CreateHeader ("PeerVia", String.Empty, RemoteAddress));
                                pc.Channel.SendMessage (message);
                        }
                }
@@ -283,13 +330,14 @@ message = mb.CreateMessage ();
                        sba.InstanceContextMode = InstanceContextMode.Single;
                        sba.IncludeExceptionDetailInFaults = true;
 
-                       var se = listener_host.AddServiceEndpoint (typeof (IPeerReceiverContract), binding, "net.p2p://" + node.MeshId);
+                       var se = listener_host.AddServiceEndpoint (typeof (IPeerConnectorContract).FullName, binding, "net.p2p://" + node.MeshId + "/");
                        se.ListenUri = uri;
                        listener_host.Open (timeout - (DateTime.Now - start));
 
                        var nid = new Random ().Next (0, int.MaxValue);
                        var ea = new EndpointAddress (uri);
                        var pna = new PeerNodeAddress (ea, new ReadOnlyCollection<IPAddress> (Dns.GetHostEntry (name).AddressList));
+                       local_node_address = pna;
                        node.RegisteredId = resolver.Register (node.MeshId, pna, timeout - (DateTime.Now - start));
                        node.NodeId = nid;
 
index 6c2c81db3d6662a359b5862edeff9e22b6657e62..80bf02ff27f1a1212a100036b8ce31e831233679 100644 (file)
@@ -57,10 +57,20 @@ namespace System.ServiceModel.Channels
                public ReplyChannelBase (ChannelListenerBase listener)
                        : base (listener)
                {
+                       this.listener = listener;
                }
 
+               ChannelListenerBase listener;
+
                public abstract EndpointAddress LocalAddress { get; }
 
+               public override T GetProperty<T> ()
+               {
+                       if (typeof (T) == typeof (IChannelListener))
+                               return (T) (object) listener;
+                       return base.GetProperty<T> ();
+               }
+
                protected override void OnAbort ()
                {
                        OnClose (TimeSpan.Zero);
index 392ea2d6bc3bd8399bb28ec362129bb41305961e..ee29936c58be5beb81d6aad7cacfecb5cb67b333 100644 (file)
@@ -66,6 +66,13 @@ namespace System.ServiceModel.Channels
                        get { return via ?? RemoteAddress.Uri; }
                }
 
+               public override T GetProperty<T> ()
+               {
+                       if (typeof (T) == typeof (IChannelFactory))
+                               return (T) (object) channel_factory;
+                       return base.GetProperty<T> ();
+               }
+
                // Request
 
                public Message Request (Message message)
index 6940eeb7f9db6e8f3fa08a1deef3082177f79e64..54b8bc5d4d7166e9567dfa7df68964f5fb7bb684 100644 (file)
@@ -111,7 +111,7 @@ namespace System.ServiceModel.Channels
                        if (client != null) {
                                foreach (var ch in accepted_channels) {
                                        var dch = ch as TcpDuplexSessionChannel;
-                                       if (dch == null || dch.TcpClient == null)
+                                       if (dch == null || dch.TcpClient == null && !dch.TcpClient.Connected)
                                                continue;
                                        if (((IPEndPoint) dch.TcpClient.Client.RemoteEndPoint).Equals (client.Client.RemoteEndPoint))
                                                // ... then it should be handled in another BeginTryReceive/EndTryReceive loop in ChannelDispatcher.
index 0d71219160424bfabb2fedee2a881b1fa874f56c..4f294b9358fc0544bfb74bf8f658ac92a38ca609 100644 (file)
@@ -69,6 +69,7 @@ namespace System.ServiceModel.Channels
                bool is_service_side;
                TcpBinaryFrameManager frame;
                TcpDuplexSession session; // do not use this directly. Use Session instead.
+               EndpointAddress counterpart_address;
                
                public TcpDuplexSessionChannel (ChannelFactoryBase factory, TcpChannelInfo info, EndpointAddress address, Uri via)
                        : base (factory, address, via)
@@ -79,6 +80,7 @@ namespace System.ServiceModel.Channels
                        // make sure to acquire TcpClient here.
                        int explicitPort = Via.Port;
                        client = new TcpClient (Via.Host, explicitPort <= 0 ? TcpTransportBindingElement.DefaultPort : explicitPort);
+                       counterpart_address = GetEndpointAddressFromTcpClient (client);
                }
                
                public TcpDuplexSessionChannel (ChannelListenerBase listener, TcpChannelInfo info, TcpClient client)
@@ -87,12 +89,27 @@ namespace System.ServiceModel.Channels
                        is_service_side = true;
                        this.client = client;
                        this.info = info;
+                       counterpart_address = GetEndpointAddressFromTcpClient (client);
                }
-               
+
+               EndpointAddress GetEndpointAddressFromTcpClient (TcpClient client)
+               {
+                       IPEndPoint ep = (IPEndPoint) client.Client.RemoteEndPoint;
+                       return new EndpointAddress (new Uri ("net.tcp://" + ep));
+               }
+
                public MessageEncoder Encoder {
                        get { return info.MessageEncoder; }
                }
 
+               public override EndpointAddress RemoteAddress {
+                       get { return base.RemoteAddress ?? counterpart_address; }
+               }
+
+               public override EndpointAddress LocalAddress {
+                       get { return base.LocalAddress ?? counterpart_address; }
+               }
+
                public IDuplexSession Session {
                        get {
                                if (session == null)
index 060787c16c42b394d86deae05b798e0a053871dc..1b6c520986f820a0aea419249fd6595d7af2acbf 100644 (file)
@@ -1,3 +1,45 @@
+2009-08-11  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * DataContractSerializerOperationBehavior.cs : add missing members.
+
+2009-08-11  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * MetadataExchangeClient.cs : add missing async methods.
+
+2009-08-11  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * MetadataResolver.cs : added remaining methods.
+       * MetadataExchangeClient.cs : a bit of required changes for above.
+
+2009-08-11  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * ServiceDebugBehavior.cs, ServiceMetadataBehavior.cs :
+         add Binding properties. Properties are now auto.
+       * ServiceMetadataExtension.cs : take Binding too to build dispatcher.
+
+2009-08-10  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * ServiceContractGenerator.cs : removed ChannelBase proxy stuff,
+         which will be moved to svcutil source.
+         The targets for extension should be the interface, not the client
+         class.
+
+2009-08-10  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * ServiceContractGenerator.cs,
+         OperationContractGenerationContext.cs : support extensions i.e.
+         IServiceContractGenerationExtension and IOperation...(ditto) .
+
+2009-08-10  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * ServiceContractGenerator.cs : first step to add moonlight-based
+         client proxy generator (it is not supported in 3.5. needs to be
+         enabled by some hook, such as reflection-based hack).
+
+2009-08-07  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * ContractDescription.cs : wcf & 2.1 is specially annoying land :(
+
 2009-08-07  Atsushi Enomoto  <atsushi@ximian.com>
 
        * ContractDescriptionGenerator.cs : add new contract getter to
index fe016da21355f1bc73a667308073978a1bfc7ed3..3d5660dd33e0e3a69249260a29bbfca5e1102dc5 100644 (file)
@@ -153,8 +153,10 @@ namespace System.ServiceModel.Description
                        foreach (OperationDescription od in Operations) {
                                if (!proxy.Operations.Contains (od.Name))
                                        PopulateClientOperation (proxy, od);
+#if !NET_2_1
                                foreach (IOperationBehavior ob in od.Behaviors)
                                        ob.ApplyClientBehavior (od, proxy.Operations [od.Name]);
+#endif
                        }
 
                        return proxy;
index ba801cf27cdaa8c70e671cc27a571ee1fdeaf433..58f421e75f1b436ade03daa406a7f3c56d4ae787 100644 (file)
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 using System;
+using System.Collections.Generic;
 using System.Runtime.Serialization;
 using System.ServiceModel.Channels;
 using System.ServiceModel.Dispatcher;
+using System.Xml;
 
 namespace System.ServiceModel.Description
 {
@@ -41,6 +43,7 @@ namespace System.ServiceModel.Description
                {
                        format = new DataContractFormatAttribute ();
                        this.operation = operation;
+                       MaxItemsInObjectGraph = int.MaxValue;
                }
 
                public DataContractSerializerOperationBehavior (
@@ -49,17 +52,33 @@ namespace System.ServiceModel.Description
                {
                        this.format = dataContractFormatAttribute;
                        this.operation = operation;
+                       MaxItemsInObjectGraph = int.MaxValue;
                }
 
                public DataContractFormatAttribute DataContractFormatAttribute {
                        get { return format; }
                }
 
+               public bool IgnoreExtensionDataObject { get; set; }
+
+               public int MaxItemsInObjectGraph { get; set; }
+
+               public IDataContractSurrogate DataContractSurrogate { get; set; }
+
+               public virtual XmlObjectSerializer CreateSerializer (Type type, string name, string ns, IList<Type> knownTypes)
+               {
+                       return new DataContractSerializer (type, name, ns, knownTypes, MaxItemsInObjectGraph, IgnoreExtensionDataObject, false, DataContractSurrogate);
+               }
+
+               public virtual XmlObjectSerializer CreateSerializer (Type type, XmlDictionaryString name, XmlDictionaryString ns, IList<Type> knownTypes)
+               {
+                       return new DataContractSerializer (type, name, ns, knownTypes, MaxItemsInObjectGraph, IgnoreExtensionDataObject, false, DataContractSurrogate);
+               }
+
                void IOperationBehavior.AddBindingParameters (
                        OperationDescription description,
                        BindingParameterCollection parameters)
                {
-                       throw new NotImplementedException ();
                }
 
                void IOperationBehavior.ApplyDispatchBehavior (
index 519e3c4fd74145388317f4c54097324b2cd27928..e0dce888d223e2f8b35d231fa6ff8fdf111f15ab 100644 (file)
@@ -46,21 +46,20 @@ using SMMessage = System.ServiceModel.Channels.Message;
 
 namespace System.ServiceModel.Description
 {
-       [MonoTODO]
+       [MonoTODO ("MetadataExchangeClientMode is not considered")]
        public class MetadataExchangeClient
        {
                string scheme;
 
                EndpointAddress address;
                SMBinding binding;
+               MetadataExchangeClientMode mode = MetadataExchangeClientMode.MetadataExchange;
 
+               // constructors
+
+               [MonoTODO ("use empty configuration")]
                public MetadataExchangeClient ()
                {
-                       //FIXME: Look for config element, implementing
-                       //      IMetadataExchange contract
-                       //      Use Channel<IMetadataExchange> .. ?
-                       
-                       throw new NotImplementedException ();
                }
 
                public MetadataExchangeClient (SMBinding mexBinding)
@@ -81,8 +80,11 @@ namespace System.ServiceModel.Description
                public MetadataExchangeClient (Uri address, MetadataExchangeClientMode mode)
                {
                        this.address = new EndpointAddress (address.AbsoluteUri);
+                       this.mode = mode;
                }
 
+               // sync methods
+
                public MetadataSet GetMetadata ()
                {
                        return GetMetadata (address);
@@ -91,7 +93,7 @@ namespace System.ServiceModel.Description
                public MetadataSet GetMetadata (EndpointAddress address)
                {
                        //FIXME: default mode?
-                       return GetMetadataInternal (address, MetadataExchangeClientMode.MetadataExchange);
+                       return GetMetadataInternal (address, mode);
                }
 
                public MetadataSet GetMetadata (Uri address, MetadataExchangeClientMode mode)
@@ -99,7 +101,7 @@ namespace System.ServiceModel.Description
                        return GetMetadataInternal (new EndpointAddress (address.AbsoluteUri), mode);
                }
 
-               MetadataSet GetMetadataInternal (EndpointAddress address, MetadataExchangeClientMode mode)
+               internal MetadataSet GetMetadataInternal (EndpointAddress address, MetadataExchangeClientMode mode)
                {
                        if (binding == null)
                                binding = MetadataExchangeBindings.CreateMexHttpBinding ();
@@ -127,6 +129,44 @@ namespace System.ServiceModel.Description
 
                        return MetadataSet.ReadFrom (ret.GetReaderAtBodyContents ());
                }
+
+               // async methods
+
+               Func<Func<MetadataSet>,MetadataSet> getter;
+
+               void PrepareGetter ()
+               {
+                       if (getter == null)
+                               getter = new Func<Func<MetadataSet>,MetadataSet> (GetMetadata);
+               }
+
+               public MetadataSet EndGetMetadata (IAsyncResult result)
+               {
+                       return getter.EndInvoke (result);
+               }
+
+               MetadataSet GetMetadata (Func<MetadataSet> func)
+               {
+                       return func ();
+               }
+
+               public IAsyncResult BeginGetMetadata (AsyncCallback callback, object asyncState)
+               {
+                       PrepareGetter ();
+                       return getter.BeginInvoke (() => GetMetadata (), callback, asyncState);
+               }
+
+               public IAsyncResult BeginGetMetadata (EndpointAddress address, AsyncCallback callback, object asyncState)
+               {
+                       PrepareGetter ();
+                       return getter.BeginInvoke (() => GetMetadata (address), callback, asyncState);
+               }
+
+               public IAsyncResult BeginGetMetadata (Uri address, MetadataExchangeClientMode mode, AsyncCallback callback, object asyncState)
+               {
+                       PrepareGetter ();
+                       return getter.BeginInvoke (() => GetMetadata (address, mode), callback, asyncState);
+               }
        }
        
        internal class MetadataProxy : ClientBase<IMetadataExchange>, IMetadataExchange
index 3d4fe08b4c6d7b03361c1fc06fd77e3be80723d5..84812404c2678b7359f33ba61ea4aa124296875c 100644 (file)
@@ -47,17 +47,57 @@ namespace System.ServiceModel.Description
        [MonoTODO]
        public static class MetadataResolver
        {
-               public static ServiceEndpointCollection Resolve (
-                               Type contract,
-                               EndpointAddress address)
+               static IEnumerable<ContractDescription> ToContracts (Type contract)
                {
                        if (contract == null)
                                throw new ArgumentNullException ("contract");
+                       yield return ContractDescription.GetContract (contract);
+               }
+
+               public static IAsyncResult BeginResolve (Type contract, EndpointAddress address, AsyncCallback callback, object asyncState)
+               {
+                       return BeginResolve (ToContracts (contract), address, callback, asyncState);
+               }
+
+               public static IAsyncResult BeginResolve (IEnumerable<ContractDescription> contracts, EndpointAddress address, AsyncCallback callback, object asyncState)
+               {
+                       return BeginResolve (contracts, address, MetadataExchangeClientMode.MetadataExchange, callback, asyncState);
+               }
+
+               public static IAsyncResult BeginResolve (Type contract, Uri address, MetadataExchangeClientMode mode, AsyncCallback callback, object asyncState)
+               {
+                       return BeginResolve (ToContracts (contract), new EndpointAddress (address), mode, callback, asyncState);
+               }
+
+               public static IAsyncResult BeginResolve (IEnumerable<ContractDescription> contracts, EndpointAddress address, MetadataExchangeClientMode mode, AsyncCallback callback, object asyncState)
+               {
+                       return BeginResolve (contracts, address, mode, new MetadataExchangeClient (), callback, asyncState);
+               }
+
+               public static IAsyncResult BeginResolve (Type contract, EndpointAddress address, MetadataExchangeClient client, AsyncCallback callback, object asyncState)
+               {
+                       return resolver.BeginInvoke (ToContracts (contract), () => client.GetMetadata (address), callback, asyncState);
+               }
+
+               public static IAsyncResult BeginResolve (IEnumerable<ContractDescription> contracts, EndpointAddress address, MetadataExchangeClientMode mode, MetadataExchangeClient client, AsyncCallback callback, object asyncState)
+               {
+                       return resolver.BeginInvoke (contracts, () => client.GetMetadataInternal (address, mode), callback, asyncState);
+               }
+
+               delegate ServiceEndpointCollection Resolver (IEnumerable<ContractDescription> contracts, Func<MetadataSet> metadataGetter);
+
+               static readonly Resolver resolver = new Resolver (ResolveContracts);
 
-                       return ResolveContracts (
-                                       new ContractDescription [] {ContractDescription.GetContract (contract)},
-                                       address, 
-                                       MetadataExchangeClientMode.MetadataExchange);
+               public static ServiceEndpointCollection EndResolve (IAsyncResult result)
+               {
+                       return resolver.EndInvoke (result);
+               }
+
+               public static ServiceEndpointCollection Resolve (
+                               Type contract,
+                               EndpointAddress address)
+               {
+                       return Resolve (ToContracts (contract), address);
                }
 
                public static ServiceEndpointCollection Resolve (
@@ -65,17 +105,14 @@ namespace System.ServiceModel.Description
                                Uri address,
                                MetadataExchangeClientMode mode)
                {
-                       return ResolveContracts (
-                                       new ContractDescription [] {ContractDescription.GetContract (contract)},
-                                       address, 
-                                       mode);
+                       return Resolve (ToContracts (contract), address, mode);
                }
 
                public static ServiceEndpointCollection Resolve (
                                IEnumerable<ContractDescription> contracts,
                                EndpointAddress address)
                {
-                       return ResolveContracts (contracts, address, MetadataExchangeClientMode.MetadataExchange);
+                       return Resolve (contracts, address, new MetadataExchangeClient ());
                }
 
                public static ServiceEndpointCollection Resolve (
@@ -83,7 +120,7 @@ namespace System.ServiceModel.Description
                                Uri address,
                                MetadataExchangeClientMode mode)
                {
-                       return ResolveContracts (contracts, address, mode);
+                       return Resolve (contracts, new EndpointAddress (address), new MetadataExchangeClient (address, mode));
                }
 
                public static ServiceEndpointCollection Resolve (
@@ -94,8 +131,7 @@ namespace System.ServiceModel.Description
                        if (client == null)
                                throw new ArgumentNullException ("client");
 
-                       /* FIXME: client is used for what? */
-                       return ResolveContracts (contracts, address, MetadataExchangeClientMode.MetadataExchange);
+                       return ResolveContracts (contracts, () => client.GetMetadata (address));
                }
 
                /* FIXME: What is the mode/client used for here? 
@@ -109,24 +145,12 @@ namespace System.ServiceModel.Description
                        if (client == null)
                                throw new ArgumentNullException ("client");
 
-                       return ResolveContracts (contracts, address, mode);
+                       return ResolveContracts (contracts, () => new MetadataExchangeClient ().GetMetadata (address, mode));
                }
 
                private static ServiceEndpointCollection ResolveContracts (
                                IEnumerable<ContractDescription> contracts,
-                               Uri address,
-                               MetadataExchangeClientMode mode)
-               {
-                       if (address == null)
-                               throw new ArgumentNullException ("address");
-
-                       return ResolveContracts (contracts, new EndpointAddress (address), mode);
-               }
-
-               private static ServiceEndpointCollection ResolveContracts (
-                               IEnumerable<ContractDescription> contracts,
-                               EndpointAddress address,
-                               MetadataExchangeClientMode mode)
+                               Func<MetadataSet> metadataGetter)
                {
                        if (contracts == null)
                                throw new ArgumentNullException ("contracts");
@@ -135,11 +159,7 @@ namespace System.ServiceModel.Description
                        if (list.Count == 0)
                                throw new ArgumentException ("There must be atleast one ContractDescription", "contracts");
 
-                       if (address == null)
-                               throw new ArgumentNullException ("address");
-
-                       MetadataExchangeClient client = new MetadataExchangeClient (address);
-                       MetadataSet metadata = client.GetMetadata ();
+                       MetadataSet metadata = metadataGetter ();
                        WsdlImporter importer = new WsdlImporter (metadata);
                        ServiceEndpointCollection endpoints = importer.ImportAllEndpoints ();
                        
index 841cf56d9aaa1c237cd9687c4c7691218ec143c9..274a2be62be773633fde11e04d6763c3161419a5 100644 (file)
@@ -44,7 +44,7 @@ namespace System.ServiceModel.Description
                        CodeTypeDeclaration declaringType,
                        CodeMemberMethod method)
                        : this (serviceContractGenerator, contract, operation,
-                               declaringType, false, method, null)
+                               declaringType, method, null, null)
                {
                }
 
@@ -53,38 +53,24 @@ namespace System.ServiceModel.Description
                        ServiceContractGenerationContext contract,
                        OperationDescription operation,
                        CodeTypeDeclaration declaringType,
+                       CodeMemberMethod method,
                        CodeMemberMethod beginMethod,
                        CodeMemberMethod endMethod)
-                       : this (serviceContractGenerator, contract, operation,
-                               declaringType, true, beginMethod, endMethod)
-               {
-               }
-
-               private OperationContractGenerationContext (
-                       ServiceContractGenerator serviceContractGenerator,
-                       ServiceContractGenerationContext contract,
-                       OperationDescription operation,
-                       CodeTypeDeclaration declaringType,
-                       bool isAsync,
-                       CodeMemberMethod method, // sync
-                       CodeMemberMethod endMethod) // async
                {
                        generator = serviceContractGenerator;
                        this.contract = contract;
                        this.operation = operation;
                        declaring_type = declaringType;
                        this.method = method;
+                       this.begin_method = beginMethod;
                        this.end_method = endMethod;
-                       is_async = isAsync;
                }
 
-               bool is_async;
                ServiceContractGenerator generator;
                ServiceContractGenerationContext contract;
                OperationDescription operation;
                CodeTypeDeclaration declaring_type;
-               CodeMemberMethod method;
-               CodeMemberMethod end_method;
+               CodeMemberMethod method, begin_method, end_method;
 
                public ServiceContractGenerator ServiceContractGenerator {
                        get { return generator; }
@@ -98,14 +84,17 @@ namespace System.ServiceModel.Description
                public CodeTypeDeclaration DeclaringType {
                        get { return declaring_type; }
                }
-               public CodeMemberMethod Method {
+               public CodeMemberMethod SyncMethod {
                        get { return method; }
                }
+               public CodeMemberMethod BeginMethod {
+                       get { return begin_method; }
+               }
                public CodeMemberMethod EndMethod {
                        get { return end_method; }
                }
                public bool IsAsync {
-                       get { return is_async; }
+                       get { return begin_method != null; }
                }
        }
 }
index 4d79e7ed349963739e26a922ffeda2ef734c3a38..433bf39568187c3f047580092641269ed9429126 100644 (file)
@@ -40,6 +40,7 @@ using System.Xml.Serialization;
 
 using ConfigurationType = System.Configuration.Configuration;
 using QName = System.Xml.XmlQualifiedName;
+using OPair = System.Collections.Generic.KeyValuePair<System.ServiceModel.Description.IOperationContractGenerationExtension,System.ServiceModel.Description.OperationContractGenerationContext>;
 
 namespace System.ServiceModel.Description
 {
@@ -55,6 +56,8 @@ namespace System.ServiceModel.Description
                        = new Dictionary<ContractDescription,Type> ();
                ServiceContractGenerationOptions options;
                Dictionary<QName, QName> imported_names = null;
+               ServiceContractGenerationContext contract_context;
+               List<OPair> operation_contexts = new List<OPair> ();
 
                public ServiceContractGenerator ()
                        : this (null, null)
@@ -130,15 +133,27 @@ namespace System.ServiceModel.Description
                {
                        CodeNamespace cns = GetNamespace (contractDescription.Namespace);
                        imported_names = new Dictionary<QName, QName> ();
-                       try {
-                               return ExportInterface (contractDescription, cns);
-                       } finally {
-                               if ((Options & ServiceContractGenerationOptions.ClientClass) != 0)
-                                       GenerateProxyClass (contractDescription, cns);
-
-                               if ((Options & ServiceContractGenerationOptions.ChannelInterface) != 0)
-                                       GenerateChannelInterface (contractDescription, cns);
+                       var ret = ExportInterface (contractDescription, cns);
+
+                       // FIXME: handle duplex callback
+
+                       if ((Options & ServiceContractGenerationOptions.ChannelInterface) != 0)
+                               GenerateChannelInterface (contractDescription, cns);
+
+                       if ((Options & ServiceContractGenerationOptions.ClientClass) != 0)
+                               GenerateProxyClass (contractDescription, cns);
+
+                       // Process extensions. Class first, then methods.
+                       // (built-in ones must present before processing class extensions).
+                       foreach (var cb in contractDescription.Behaviors) {
+                               var gex = cb as IServiceContractGenerationExtension;
+                               if (gex != null)
+                                       gex.GenerateContract (contract_context);
                        }
+                       foreach (var opair in operation_contexts)
+                               opair.Key.GenerateOperation (opair.Value);
+
+                       return ret;
                }
 
                CodeNamespace GetNamespace (string ns)
@@ -239,7 +254,7 @@ namespace System.ServiceModel.Description
                        type.Members.Add (ctor);
 
                        // service contract methods
-                       AddImplementationMethods (type, cd);
+                       AddImplementationClientMethods (type, cd);
                }
 
                void GenerateChannelInterface (ContractDescription cd, CodeNamespace cns)
@@ -274,6 +289,8 @@ namespace System.ServiceModel.Description
                                                typeof (ServiceContractAttribute)));
                        ad.Arguments.Add (new CodeAttributeArgument ("Namespace", new CodePrimitiveExpression (cd.Namespace)));
                        type.CustomAttributes.Add (ad);
+                       contract_context = new ServiceContractGenerationContext (this, cd, type);
+
                        AddOperationMethods (type, cd);
 
                        return new CodeTypeReference (type.Name);
@@ -290,12 +307,17 @@ namespace System.ServiceModel.Description
                void AddOperationMethods (CodeTypeDeclaration type, ContractDescription cd)
                {
                        foreach (OperationDescription od in cd.Operations) {
+                               CodeMemberMethod syncMethod = null, beginMethod = null, endMethod = null;
+
                                CodeMemberMethod cm = new CodeMemberMethod ();
                                type.Members.Add (cm);
-                               if (GenerateAsync)
+                               if (GenerateAsync) {
                                        cm.Name = "Begin" + od.Name;
-                               else
+                                       beginMethod = cm;
+                               } else {
                                        cm.Name = od.Name;
+                                       syncMethod = cm;
+                               }
                                CodeTypeReference returnTypeFromMessageContract = null;
 
                                if (od.SyncMethod != null) {
@@ -331,20 +353,27 @@ namespace System.ServiceModel.Description
                                cm.CustomAttributes.Add (ad);
 
                                // For async mode, add EndXxx() too.
-                               if (!GenerateAsync)
-                                       return;
+                               if (GenerateAsync) {
 
-                               cm = new CodeMemberMethod ();
-                               type.Members.Add (cm);
-                               cm.Name = "End" + od.Name;
+                                       cm = new CodeMemberMethod ();
+                                       type.Members.Add (cm);
+                                       cm.Name = "End" + od.Name;
+                                       endMethod = cm;
 
-                               var res = new CodeParameterDeclarationExpression (new CodeTypeReference (typeof (IAsyncResult)), "result");
-                               cm.Parameters.Add (res);
+                                       var res = new CodeParameterDeclarationExpression (new CodeTypeReference (typeof (IAsyncResult)), "result");
+                                       cm.Parameters.Add (res);
 
-                               if (od.SyncMethod != null) // FIXME: it depends on sync method!
-                                       cm.ReturnType = new CodeTypeReference (od.SyncMethod.ReturnType);
-                               else
-                                       cm.ReturnType = returnTypeFromMessageContract;
+                                       if (od.SyncMethod != null) // FIXME: it depends on sync method!
+                                               cm.ReturnType = new CodeTypeReference (od.SyncMethod.ReturnType);
+                                       else
+                                               cm.ReturnType = returnTypeFromMessageContract;
+                               }
+
+                               foreach (var ob in od.Behaviors) {
+                                       var gex = ob as IOperationContractGenerationExtension;
+                                       if (gex != null)
+                                               operation_contexts.Add (new OPair (gex, new OperationContractGenerationContext (this, contract_context, od, type, syncMethod, beginMethod, endMethod)));
+                               }
                        }
                }
 
@@ -357,7 +386,7 @@ namespace System.ServiceModel.Description
                                                pi.Name));
                }
 
-               void AddImplementationMethods (CodeTypeDeclaration type, ContractDescription cd)
+               void AddImplementationClientMethods (CodeTypeDeclaration type, ContractDescription cd)
                {
                        foreach (OperationDescription od in cd.Operations) {
                                CodeMemberMethod cm = new CodeMemberMethod ();
@@ -410,6 +439,8 @@ namespace System.ServiceModel.Description
                                // EndXxx() implementation
 
                                cm = new CodeMemberMethod ();
+                               cm.Attributes = MemberAttributes.Public 
+                                               | MemberAttributes.Final;
                                type.Members.Add (cm);
                                cm.Name = "End" + od.Name;
 
@@ -480,7 +511,7 @@ namespace System.ServiceModel.Description
                {
                        throw new NotImplementedException ();
                }
-               
+
                private void ExportDataContract (XmlTypeMapping mapping)
                {
                        if (mapping == null)
index 86aaecc092e54622e77150c02cc2e9dd492ba377..edc8a67385ad7a6f1f3c26082927e5e257ed24f3 100644 (file)
@@ -34,39 +34,23 @@ namespace System.ServiceModel.Description
 {
        public class ServiceDebugBehavior : IServiceBehavior
        {
-               bool inc_details;
-               bool http_help_enabled = true;
-               bool https_help_enabled = true;
-               Uri http_help_url, https_help_url;
-
                public ServiceDebugBehavior ()
                {
                }
 
-               public bool IncludeExceptionDetailInFaults {
-                       get { return inc_details; }
-                       set { inc_details = value; }
-               }
+               public bool IncludeExceptionDetailInFaults { get; set; }
 
-               public bool HttpHelpPageEnabled {
-                       get { return http_help_enabled; }
-                       set { http_help_enabled = value; }
-               }
+               public bool HttpHelpPageEnabled { get; set; }
 
-               public Uri HttpHelpPageUrl {
-                       get { return http_help_url; }
-                       set { http_help_url = value; }
-               }
+               public Uri HttpHelpPageUrl { get; set; }
 
-               public bool HttpsHelpPageEnabled {
-                       get { return https_help_enabled; }
-                       set { https_help_enabled = value; }
-               }
+               public bool HttpsHelpPageEnabled { get; set; }
 
-               public Uri HttpsHelpPageUrl {
-                       get { return https_help_url; }
-                       set { https_help_url = value; }
-               }
+               public Uri HttpsHelpPageUrl { get; set; }
+
+               public Binding HttpHelpPageBinding { get; set; }
+
+               public Binding HttpsHelpPageBinding { get; set; }
 
                void IServiceBehavior.AddBindingParameters (
                        ServiceDescription description,
@@ -90,13 +74,13 @@ namespace System.ServiceModel.Description
                        if (HttpHelpPageEnabled) {
                                Uri uri = serviceHostBase.CreateUri ("http", HttpHelpPageUrl);
                                if (uri != null)
-                                       ServiceMetadataExtension.EnsureServiceMetadataHttpChanelDispatcher (description, serviceHostBase, sme, uri);
+                                       ServiceMetadataExtension.EnsureServiceMetadataHttpChanelDispatcher (description, serviceHostBase, sme, uri, HttpHelpPageBinding);
                        }
 
                        if (HttpsHelpPageEnabled) {
                                Uri uri = serviceHostBase.CreateUri ("https", HttpsHelpPageUrl);
                                if (uri != null)
-                                       ServiceMetadataExtension.EnsureServiceMetadataHttpsChanelDispatcher (description, serviceHostBase, sme, uri);
+                                       ServiceMetadataExtension.EnsureServiceMetadataHttpsChanelDispatcher (description, serviceHostBase, sme, uri, HttpsHelpPageBinding);
                        }
                }
 
index 36f839897120a110eb32b8033170807cb86d811b..dca58b48072a33db10b3560c190fc22e0517aa3e 100644 (file)
@@ -41,45 +41,31 @@ namespace System.ServiceModel.Description
        {
                public const string MexContractName = "IMetadataExchange";
 
-               bool enable_http, enable_https;
-               Uri http_url, https_url, location;
                MetadataExporter exporter;
 
                public ServiceMetadataBehavior ()
                {
                }
 
-               public bool HttpGetEnabled {
-                       get { return enable_http; }
-                       set { enable_http = value; }
-               }
+               public bool HttpGetEnabled { get; set; }
 
-               public bool HttpsGetEnabled {
-                       get { return enable_https; }
-                       set { enable_https = value; }
-               }
+               public bool HttpsGetEnabled { get; set; }
 
                public MetadataExporter MetadataExporter {
                        get { return exporter ?? (exporter = new WsdlExporter ()); }
                        set { exporter = value; }
                }
 
-               public Uri ExternalMetadataLocation {
-                       get { return location; }
-                       set { location = value; }
-               }
+               public Uri ExternalMetadataLocation { get; set; }
 
-               public Uri HttpGetUrl {
-                       get { return http_url; }
-                       set { http_url = value; }
-               }
+               public Uri HttpGetUrl { get; set; }
 
-               public Uri HttpsGetUrl {
-                       get { return https_url; }
-                       set { https_url = value; }
-               }
+               public Uri HttpsGetUrl { get; set; }
+
+               public Binding HttpGetBinding { get; set; }
+
+               public Binding HttpsGetBinding { get; set; }
 
-               [MonoTODO]
                void IServiceBehavior.AddBindingParameters (
                        ServiceDescription description,
                        ServiceHostBase serviceHostBase,
@@ -110,13 +96,13 @@ namespace System.ServiceModel.Description
                        if (HttpGetEnabled) {
                                Uri uri = serviceHostBase.CreateUri ("http", HttpGetUrl);
                                if (uri != null)
-                                       ServiceMetadataExtension.EnsureServiceMetadataHttpChanelDispatcher (description, serviceHostBase, sme, uri);
+                                       ServiceMetadataExtension.EnsureServiceMetadataHttpChanelDispatcher (description, serviceHostBase, sme, uri, HttpGetBinding);
                        }
 
                        if (HttpsGetEnabled) {
                                Uri uri = serviceHostBase.CreateUri ("https", HttpsGetUrl);
                                if (uri != null)
-                                       ServiceMetadataExtension.EnsureServiceMetadataHttpsChanelDispatcher (description, serviceHostBase, sme, uri);
+                                       ServiceMetadataExtension.EnsureServiceMetadataHttpsChanelDispatcher (description, serviceHostBase, sme, uri, HttpsGetBinding);
                        }
                }
 
index 5dc8af1bacd4a99aa5059cb11c42e0f6236ee15a..efb346bdf215a5c6e33817302864be4042ae9e7c 100644 (file)
@@ -44,7 +44,7 @@ using System.Xml.Schema;
 using WSServiceDescription = System.Web.Services.Description.ServiceDescription;
 using WSMessage = System.Web.Services.Description.Message;
 using SMMessage = System.ServiceModel.Channels.Message;
-
+using WCFBinding = System.ServiceModel.Channels.Binding;
 
 namespace System.ServiceModel.Description
 {
@@ -91,14 +91,25 @@ namespace System.ServiceModel.Description
                        return sme;
                }
 
-               internal static void EnsureServiceMetadataHttpChanelDispatcher (ServiceDescription description, ServiceHostBase serviceHostBase, ServiceMetadataExtension sme, Uri uri) {
+               internal static void EnsureServiceMetadataHttpChanelDispatcher (ServiceDescription description, ServiceHostBase serviceHostBase, ServiceMetadataExtension sme, Uri uri, WCFBinding binding)
+               {
+                       EnsureServiceMetadataDispatcher (description, serviceHostBase, sme, uri, binding ?? MetadataExchangeBindings.CreateMexHttpBinding ());
+               }
+
+               internal static void EnsureServiceMetadataHttpsChanelDispatcher (ServiceDescription description, ServiceHostBase serviceHostBase, ServiceMetadataExtension sme, Uri uri, WCFBinding binding)
+               {
+                       // same as http now.
+                       EnsureServiceMetadataDispatcher (description, serviceHostBase, sme, uri, binding ?? MetadataExchangeBindings.CreateMexHttpsBinding ());
+               }
 
+               static void EnsureServiceMetadataDispatcher (ServiceDescription description, ServiceHostBase serviceHostBase, ServiceMetadataExtension sme, Uri uri, WCFBinding binding)
+               {
                        if (sme._serviceMetadataChanelDispatchers == null)
                                sme._serviceMetadataChanelDispatchers = new Dictionary<Uri, ChannelDispatcherBase> ();
                        else if (sme._serviceMetadataChanelDispatchers.ContainsKey (uri))
                                return;
 
-                       CustomBinding cb = new CustomBinding (new BasicHttpBinding ())
+                       CustomBinding cb = new CustomBinding (binding)
                        {
                                Name = ServiceMetadataBehaviorHttpGetBinding,
                        };
@@ -117,10 +128,6 @@ namespace System.ServiceModel.Description
                        serviceHostBase.ChannelDispatchers.Add (channelDispatcher);
                }
 
-               internal static void EnsureServiceMetadataHttpsChanelDispatcher (ServiceDescription description, ServiceHostBase serviceHostBase, ServiceMetadataExtension sme, Uri uri) {
-                       throw new NotImplementedException ();
-               }
-
                void IExtension<ServiceHostBase>.Attach (ServiceHostBase owner)
                {
                        this.owner = owner;
index dbe680b6e56c4a81486c81e2fad685d05b87cba2..572f79a0fa8184b859c4600cc2bcbe4406ba0575 100644 (file)
@@ -157,8 +157,10 @@ namespace System.ServiceModel.Dispatcher
                        {
                                int index = 0;
                                foreach (ParameterInfo pi in requestMethodParams)
-                                       if (!pi.IsOut)
-                                               parameters [pi.Position] = parts [index++];
+                                       if (!pi.IsOut) {
+                                               parameters [index] = parts [index];
+                                               index++;
+                                       }
                        }
                }
 
index b4f30d194bdf61cf747de48f9b2ac4720428ea24..f7bc425ec96183905d92e15814f24adcc56a13fe 100644 (file)
@@ -1,3 +1,19 @@
+2009-08-17  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * EndpointDispatcher.cs : do not try to create wrong filter.
+
+2009-08-14  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * ChannelDispatcher.cs : EndpointNotFoundException message could
+         be a bit kindful.
+
+2009-08-11  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * IOperationInvoker.cs : fix interface.
+       * DefaultOperationInvoker.cs : refresh implementation of the above.
+       * BaseMessagesFormatter.cs, OperationInvokerHandler.cs :
+         dependent changes for above.
+
 2009-08-07  Atsushi Enomoto  <atsushi@ximian.com>
 
        * InputOrReplyRequestProcessor.cs : now it could return an instance
index 234b647ab9141414b04b534fd2f50c408aca520a..4ad1ab0804fa7149f5621866c9748f39397c8e23 100644 (file)
@@ -568,7 +568,7 @@ namespace System.ServiceModel.Dispatcher
                                        }
                                }
                                if (candidate == null)
-                                       throw new EndpointNotFoundException (String.Format ("The request message has the target '{0}' which is not reachable in this service contract", message.Headers.To));
+                                       throw new EndpointNotFoundException (String.Format ("The request message has the target '{0}' with action '{1}' which is not reachable in this service contract", message.Headers.To, message.Headers.Action));
                                return candidate;
                        }
                }
diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/DefaultOperationInvoker.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/DefaultOperationInvoker.cs
new file mode 100644 (file)
index 0000000..44912ba
--- /dev/null
@@ -0,0 +1,131 @@
+//
+// DefaultOperationInvoker.cs
+//
+// Author: Atsushi Enomoto (atsushi@ximian.com)
+//
+// Copyright (C) 2009 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections.Generic;
+using System.ServiceModel;
+using System.ServiceModel.Description;
+using System.Reflection;
+using System.Threading;
+
+namespace System.ServiceModel.Dispatcher
+{
+       class DefaultOperationInvoker : IOperationInvoker
+       {
+               readonly OperationDescription od;
+               readonly ParameterInfo [] in_params, out_params;
+
+               public DefaultOperationInvoker (OperationDescription od)
+               {
+                       this.od = od;
+                       var mi = od.SyncMethod ?? od.BeginMethod;
+                       var il = new List<ParameterInfo> ();
+                       var ol = new List<ParameterInfo> ();
+                       var pl = mi.GetParameters ();
+                       int count = mi == od.BeginMethod ? pl.Length - 2 : pl.Length;
+                       for (int i = 0; i < count; i++) {
+                               var pi = pl [i];
+                               if (!pi.IsOut)
+                                       il.Add (pi);
+                               if (pi.IsOut)
+                                       ol.Add (pi);
+                       }
+                       in_params = il.ToArray ();
+                       out_params = ol.ToArray ();
+               }
+
+               public bool IsSynchronous {
+                       get { return true; }
+               }
+
+               public object [] AllocateInputs ()
+               {
+                       return new object [in_params.Length];
+               }
+
+               public object Invoke (object instance, object [] inputs, out object [] outputs)
+               {
+                       var arr = new object [in_params.Length + out_params.Length];
+                       for (int i = 0; i < in_params.Length; i++)
+                               arr [in_params [i].Position] = inputs [i];
+
+                       var ret = od.SyncMethod.Invoke (instance, arr);
+
+                       outputs = new object [out_params.Length];
+                       for (int i = 0; i < out_params.Length; i++)
+                               outputs [i] = arr [out_params [i].Position];
+
+                       return ret;
+               }
+
+               public IAsyncResult InvokeBegin (object instance, object [] inputs, AsyncCallback callback, object state)
+               {
+                       var arr = new object [in_params.Length + out_params.Length + 2];
+                       for (int i = 0; i < in_params.Length; i++)
+                               arr [in_params [i].Position] = inputs [i];
+                       arr [arr.Length - 2] = callback;
+                       arr [arr.Length - 1] = state;
+                       return new InvokeAsyncResult (arr, (IAsyncResult) od.BeginMethod.Invoke (instance, arr));
+               }
+
+               public object InvokeEnd (object instance, out object [] outputs, IAsyncResult result)
+               {
+                       var r = (InvokeAsyncResult) result;
+                       var ret = od.EndMethod.Invoke (instance, new object [] {r.Source});
+                       var arr = r.Parameters;
+                       outputs = new object [out_params.Length];
+                       for (int i = 0; i < out_params.Length; i++)
+                               outputs [i] = arr [out_params [i].Position];
+                       return ret;
+               }
+
+               class InvokeAsyncResult : IAsyncResult
+               {
+                       public InvokeAsyncResult (object [] parameters, IAsyncResult source)
+                       {
+                               Source = source;
+                               Parameters = parameters;
+                       }
+
+                       public IAsyncResult Source;
+                       public object [] Parameters;
+
+                       public WaitHandle AsyncWaitHandle {
+                               get { return Source.AsyncWaitHandle; }
+                       }
+                       public bool CompletedSynchronously {
+                               get { return Source.CompletedSynchronously; }
+                       }
+                       public bool IsCompleted {
+                               get { return Source.IsCompleted; }
+                       }
+                       public object AsyncState {
+                               get { return Source.AsyncState; }
+                       }
+               }
+       }
+}
index eecb1028fccd52dcf97489e131ee2bc951590fa9..950a7b2664b76aabe5361d8e28a4eebfaeac30d1 100644 (file)
@@ -86,7 +86,7 @@ namespace System.ServiceModel.Dispatcher
                }
 
                public MessageFilter AddressFilter {
-                       get { return address_filter ?? (address_filter = new EndpointAddressMessageFilter (EndpointAddress)); }
+                       get { return address_filter; }
                        set {
                                if (value == null)
                                        throw new ArgumentNullException ("value");
index 048a47bb5cfcfe4489b7f2e900b2f658381a634e..077d0f0b7a5f9a82d7c0487f55a48960ca05eacc 100644 (file)
@@ -32,8 +32,8 @@ namespace System.ServiceModel.Dispatcher
        public interface IOperationInvoker
        {
                bool IsSynchronous { get; }
-               object [] AllocateParameters ();
-               object Invoke (object instance, object [] inputs);
+               object [] AllocateInputs ();
+               object Invoke (object instance, object [] inputs, out object [] outputs);
                IAsyncResult InvokeBegin (object instance, object [] inputs, 
                        AsyncCallback callback, object state);
                object InvokeEnd (object instance, out object [] outputs, IAsyncResult result);
index 6706a4d2da652c1825285c154315950670e3c393..ddd691610335b5ecb9552b55b3523401aecf72e1 100644 (file)
@@ -31,12 +31,12 @@ namespace System.ServiceModel.Dispatcher
                        DispatchOperation operation = mrc.Operation;
                        Message req = mrc.IncomingMessage;
                        object instance = mrc.InstanceContext.GetServiceInstance(req);
-                       object [] parameters;                   
+                       object [] parameters, outParams;
                        BuildInvokeParams (mrc, out parameters);
 
                        if (operation.Invoker.IsSynchronous) {
-                               object result = operation.Invoker.Invoke (instance, parameters);
-                               HandleInvokeResult (mrc, parameters, result);
+                               object result = operation.Invoker.Invoke (instance, parameters, out outParams);
+                               HandleInvokeResult (mrc, outParams, result);
                        } else {// asynchronous
                                InvokeAsynchronous (mrc, instance, parameters);
                        }                       
@@ -112,7 +112,7 @@ namespace System.ServiceModel.Dispatcher
                        EnsureValid (operation);
 
                        if (operation.DeserializeRequest) {
-                               parameters = operation.Invoker.AllocateParameters ();
+                               parameters = operation.Invoker.AllocateInputs ();
                                operation.Formatter.DeserializeRequest (mrc.IncomingMessage, parameters);
                        } else
                                parameters = new object [] { mrc.IncomingMessage };
index 4c9e23df3a2274123026a3a337fca4574b65c118..df8f77089ad6ee1fcf5fce85600860f25a93f656 100644 (file)
@@ -1,3 +1,25 @@
+2009-08-17  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * IPeerConnectorContract.cs : use wildcard for the actual message
+         transfer operation.
+
+2009-08-17  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * IPeerConnectorContract.cs : fix internal member name to get
+         serialized correctly.
+
+2009-08-14  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * IPeerConnectorContract.cs : add itself as CallbackContract.
+
+2009-08-14  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * IPeerConnectorContract.cs : remove receiver contract.
+
+2009-08-14  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * IPeerConnectorContract.cs : add Disconnect() to receiver contract.
+
 2009-08-07  Atsushi Enomoto  <atsushi@ximian.com>
 
        * IPeerConnectorContract.cs : add callback contract.
index a63f1551b26f3b56f5b5ea8a4d9fdb084d5824cd..562f6bbe6701c8f22afc027c3e7781f19d219af9 100644 (file)
@@ -12,7 +12,7 @@ namespace System.ServiceModel.PeerResolvers
                public const string Namespace = "http://schemas.microsoft.com/net/2006/05/peer";
        }
 
-       [ServiceContract (Namespace = Consts.Namespace, SessionMode = SessionMode.Allowed)]
+       [ServiceContract (Namespace = Consts.Namespace, SessionMode = SessionMode.Allowed, CallbackContract = typeof (IPeerConnectorContract))]
        internal interface IPeerConnectorContract
        {
                [OperationContract (Action = Consts.Namespace + "/Connect", IsOneWay = true)]
@@ -33,17 +33,7 @@ namespace System.ServiceModel.PeerResolvers
                [OperationContract (Action = Consts.Namespace + "/Ping", IsOneWay = true)]
                void Ping ();
 
-               [OperationContract (IsOneWay = true)]
-               void SendMessage (Message msg);
-       }
-
-       [ServiceContract (Namespace = Consts.Namespace, SessionMode = SessionMode.Allowed, CallbackContract = typeof (IPeerConnectorContract))]
-       internal interface IPeerReceiverContract
-       {
-               [OperationContract (Action = Consts.Namespace + "/Connect", IsOneWay = true)]
-               void Connect (ConnectInfo connect);
-
-               [OperationContract (IsOneWay = true)]
+               [OperationContract (Action = "*", IsOneWay = true)]
                void SendMessage (Message msg);
        }
 
@@ -80,7 +70,7 @@ namespace System.ServiceModel.PeerResolvers
        internal class ConnectInfoDC
        {
                [DataMember]
-               public PeerNodeAddress PeerNodeAddress { get; set; }
+               public PeerNodeAddress Address { get; set; }
                [DataMember]
                public ulong NodeId { get; set; }
        }
@@ -96,9 +86,9 @@ namespace System.ServiceModel.PeerResolvers
                [MessageBodyMember (Name = "Connect", Namespace = Consts.Namespace)]
                ConnectInfoDC dc;
 
-               public PeerNodeAddress PeerNodeAddress {
-                       get { return dc.PeerNodeAddress; }
-                       set { dc.PeerNodeAddress = value; }
+               public PeerNodeAddress Address {
+                       get { return dc.Address; }
+                       set { dc.Address = value; }
                }
 
                public ulong NodeId {
index 1388bb1bc527b6b385787975f30eb7fc529d2714..0f2fbd4ef3d0f0f6edbca8933f496f0592cbd586 100755 (executable)
@@ -614,6 +614,7 @@ System.ServiceModel.Dispatcher/ClientOperation.cs
 System.ServiceModel.Dispatcher/ClientRuntime.cs
 System.ServiceModel.Dispatcher/DataContractSerializerServiceBehavior.cs
 System.ServiceModel.Dispatcher/DefaultInstanceContextProvider.cs
+System.ServiceModel.Dispatcher/DefaultOperationInvoker.cs
 System.ServiceModel.Dispatcher/DispatchOperation.cs
 System.ServiceModel.Dispatcher/DispatchRuntime.cs
 System.ServiceModel.Dispatcher/EndpointAddressMessageFilter.cs
index 47a210cc282585548038facd459552673a4fff5f..73065cf8f8b1b57497d27fd4318b7799cf2f05b4 100644 (file)
@@ -37,6 +37,13 @@ namespace System.ServiceModel.Activation
 
 namespace System.ServiceModel
 {
+       public enum AddressFilterMode
+       {
+               Exact,
+               Prefix,
+               Any
+       }
+
        public enum AuditLevel
        {
                None,
@@ -309,6 +316,13 @@ namespace System.ServiceModel.Channels
                LaxTimestampLast,
        }
 
+       public enum SupportedAddressingMode
+       {
+               Anonymous,
+               NonAnonymous,
+               Mixed
+       }
+
        public enum TransferSession
        {
                None,
index 7d9177c3ea858ad5ed8ea824999fe658df907d63..32ca9122552a6a7d63591a8253829df7dee985d1 100755 (executable)
@@ -1,3 +1,44 @@
+2009-08-17  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * ServiceHostBase.cs : wildcard action support was not working
+         for one-way channels.
+
+2009-08-17  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * ServiceHostBase.cs : set expected AddressFilter.
+
+2009-08-17  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * EndpointAddress.cs : #if !NET_2_1 is removing code too much.
+
+2009-08-17  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * ServiceRuntimeChannel.cs : made some properties in duplex context
+         channel dispatching to internal client.
+
+2009-08-14  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * OperationContextScope.cs : check null arg.
+
+2009-08-14  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * ServiceRuntimeChannel.cs : return timeouts that are set at
+         dispatch runtime later than its .ctor(). Provide ListenUri too.
+
+2009-08-14  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * AllEnums.cs : add AddressFilterMode and SupportedAddressingMode.
+       * ServiceBehaviorAttribute.cs : added missing properties.
+
+2009-08-11  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * ClientBase.cs : (ChannelBase) now ClientRuntimeChannel demands an
+         explicit address.
+
+2009-08-11  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * ServiceHostBase.cs : use new IOperationInvoker implementation.
+
 2009-08-07  Atsushi Enomoto  <atsushi@ximian.com>
 
        * ServiceRuntimeChannel.cs : change .ctor() args.
index fb45ca455caa310b653ddde6e9cee835b3345680..b07ac73b5f9f84a08016d63ef01567793ec15909 100644 (file)
@@ -398,7 +398,7 @@ namespace System.ServiceModel
                        internal ClientRuntimeChannel Inner {
                                get {
                                        if (inner_channel == null)
-                                               inner_channel = new ClientRuntimeChannel (endpoint, factory, null, null);
+                                               inner_channel = new ClientRuntimeChannel (endpoint, factory, endpoint.Address, null);
                                        return inner_channel;
                                }
                        }
index 512051559f97498e637dd9c0d07bfa7e6910addb..8d76cb67cbf59a3b21ea13faa828a9b0f859bb4f 100644 (file)
@@ -184,7 +184,7 @@ namespace System.ServiceModel
                        return ! (address1 == address2);
                }
 
-#if !NET_2_1
+//#if !NET_2_1
                [MonoTODO]
                public static EndpointAddress ReadFrom (
                        XmlDictionaryReader reader)
@@ -278,7 +278,6 @@ namespace System.ServiceModel
                        AddressingVersion addressingVersion, XmlReader reader)
                {
                        Uri uri = null;
-                       MetadataSet metadata = null;
                        EndpointIdentity identity = null;
                        reader.MoveToContent ();
                        if (reader.LocalName == "Address" && 
@@ -292,6 +291,8 @@ namespace System.ServiceModel
                                        addressingVersion.Namespace, reader.LocalName, reader.NamespaceURI));
 
                        reader.MoveToContent ();
+#if !NET_2_1
+                       MetadataSet metadata = null;
                        if (reader.LocalName == "Metadata" &&
                            reader.NamespaceURI == addressingVersion.Namespace &&
                            !reader.IsEmptyElement) {
@@ -306,16 +307,20 @@ namespace System.ServiceModel
                                // FIXME: implement
                                reader.Skip ();
                        }
+#endif
 
                        if (addressingVersion == AddressingVersion.WSAddressing10 && uri == w3c_anonymous)
                                uri = anonymous_role;
 
+#if NET_2_1
+                       return new EndpointAddress (uri, identity);
+#else
                        if (metadata == null)
                                return new EndpointAddress (uri, identity);
                        return new EndpointAddress (uri, identity,
                                AddressHeader.CreateAddressHeader (metadata));
-               }
 #endif
+               }
 
                public override string ToString ()
                {
index 089e19459261a48ccc487ba81bf2f325dd1efea2..d4a38f63bb1e142d72d32054e6f079ff99f46450 100644 (file)
@@ -41,6 +41,8 @@ namespace System.ServiceModel
 
                public OperationContextScope (OperationContext context)
                {
+                       if (context == null)
+                               throw new ArgumentNullException ("context");
                        previous = OperationContext.Current;
                        OperationContext.Current = context;
                }
index 6d5d82110bf53de3b78a492887b10635b6cba724..f946e09214ac76ffa86754ede94c46474812ed42 100644 (file)
@@ -56,6 +56,16 @@ namespace System.ServiceModel
                string tx_timeout;
                object singleton;
 
+               [MonoTODO]
+               public string Name { get; set; }
+               [MonoTODO]
+               public string Namespace { get; set; }
+               [MonoTODO]
+               public string ConfigurationName { get; set; }
+
+               [MonoTODO]
+               public AddressFilterMode AddressFilterMode { get; set; }
+
                [MonoTODO]
                public bool AutomaticSessionShutdown { get; set; }
 
index 95c341806d87fa25796c695e93a06ff6191cc47a..5add53257d0a5960505a1bd4546d649be9de7d99 100644 (file)
@@ -389,8 +389,8 @@ namespace System.ServiceModel
 
                }
 
-               internal ChannelDispatcher BuildChannelDispatcher (ServiceEndpoint se, BindingParameterCollection commonParams) {
-
+               internal ChannelDispatcher BuildChannelDispatcher (ServiceEndpoint se, BindingParameterCollection commonParams)
+               {
                        //User the binding parameters to build the channel listener and Dispatcher
                        IChannelListener lf = BuildListener (se, commonParams);
                        ChannelDispatcher cd = new ChannelDispatcher (
@@ -404,6 +404,7 @@ namespace System.ServiceModel
                                new EndpointDispatcher (se.Address, se.Contract.Name, se.Contract.Namespace);
                        endpoint_dispatcher.DispatchRuntime.Type = Description.ServiceType;
                        endpoint_dispatcher.ContractFilter = GetContractFilter (se.Contract);
+                       endpoint_dispatcher.AddressFilter = new EndpointAddressMessageFilter (se.Address);
                        endpoint_dispatcher.ChannelDispatcher = cd;
                        cd.Endpoints.Add (endpoint_dispatcher);
                        
@@ -463,7 +464,7 @@ namespace System.ServiceModel
                                od.IsOneWay ?
                                new DispatchOperation (db, od.Name, reqA) :
                                new DispatchOperation (db, od.Name, reqA, resA);
-                       bool has_void_reply = false;
+                       bool no_serialized_reply = od.IsOneWay;
                        foreach (MessageDescription md in od.Messages) {
                                if (md.Direction == MessageDirection.Input &&
                                        md.Body.Parts.Count == 1 &&
@@ -474,25 +475,21 @@ namespace System.ServiceModel
                                        if (md.Body.ReturnValue.Type == typeof (Message))
                                                o.SerializeReply = false;
                                        else if (md.Body.ReturnValue.Type == typeof (void))
-                                               has_void_reply = true;
+                                               no_serialized_reply = true;
                                }
                        }
 
                        // Setup Invoker
-                       // FIXME: support async method
-                       if (od.SyncMethod != null)
-                               o.Invoker = new SyncMethodInvoker (od.SyncMethod);
-                       else
-                               o.Invoker = new AsyncMethodInvoker (od.BeginMethod, od.EndMethod);
+                       o.Invoker = new DefaultOperationInvoker (od);
 
                        // Setup Formater
                        o.Formatter = BaseMessagesFormatter.Create (od);
 
-                       if (o.Action == "*" && o.ReplyAction == "*") {
+                       if (o.Action == "*" && (o.IsOneWay || o.ReplyAction == "*")) {
                                //Signature : Message  (Message)
                                //          : void  (Message)
                                //FIXME: void (IChannel)
-                               if (!o.DeserializeRequest && (!o.SerializeReply || has_void_reply))
+                               if (!o.DeserializeRequest && (!o.SerializeReply || no_serialized_reply)) // what is this double-ish check for?
                                        db.UnhandledDispatchOperation = o;
                        }
 
@@ -612,6 +609,7 @@ namespace System.ServiceModel
                        Close ();
                }
 
+               /*
                class SyncMethodInvoker : IOperationInvoker
                {
                        readonly MethodInfo _methodInfo;
@@ -692,5 +690,7 @@ namespace System.ServiceModel
 
                        #endregion
                }
+               */
        }
+
 }
index 99b5f9740e408909aca4c3a82b240d33be5c1285..1cf72776b879aa21c227947a271bf04a6736be06 100644 (file)
@@ -48,6 +48,16 @@ namespace System.ServiceModel
 
                ClientRuntimeChannel client;
 
+               public override bool AllowOutputBatching {
+                       get { return client.AllowOutputBatching; }
+                       set { client.AllowOutputBatching = value; }
+               }
+
+               public virtual TimeSpan OperationTimeout {
+                       get { return client.OperationTimeout; }
+                       set { client.OperationTimeout = value; }
+               }
+
                public bool AutomaticInputSessionShutdown {
                        get { throw new NotImplementedException (); }
                        set { throw new NotImplementedException (); }
@@ -95,21 +105,19 @@ namespace System.ServiceModel
        internal class ServiceRuntimeChannel : CommunicationObject, IServiceChannel
        {
                IExtensionCollection<IContextChannel> extensions;
-               readonly IChannel channel;              
-               readonly TimeSpan _openTimeout;
-               readonly TimeSpan _closeTimeout;
+               readonly IChannel channel;
+               readonly DispatchRuntime runtime;
 
                public ServiceRuntimeChannel (IChannel channel, DispatchRuntime runtime)
                {
                        this.channel = channel;
-                       this._openTimeout = runtime.ChannelDispatcher.DefaultOpenTimeout;
-                       this._closeTimeout = runtime.ChannelDispatcher.DefaultCloseTimeout;
+                       this.runtime = runtime;
                }
 
                #region IContextChannel
 
                [MonoTODO]
-               public bool AllowOutputBatching { get; set; }
+               public virtual bool AllowOutputBatching { get; set; }
 
                public IInputSession InputSession {
                        get {
@@ -132,7 +140,7 @@ namespace System.ServiceModel
                }
 
                [MonoTODO]
-               public TimeSpan OperationTimeout { get; set; }
+               public virtual TimeSpan OperationTimeout { get; set; }
 
                public IOutputSession OutputSession {
                        get {
@@ -157,11 +165,11 @@ namespace System.ServiceModel
 
                // CommunicationObject
                protected internal override TimeSpan DefaultOpenTimeout {
-                       get { return _openTimeout; }
+                       get { return runtime.ChannelDispatcher.DefaultOpenTimeout; }
                }
 
                protected internal override TimeSpan DefaultCloseTimeout {
-                       get { return _closeTimeout; }
+                       get { return runtime.ChannelDispatcher.DefaultCloseTimeout; }
                }
 
                protected override void OnAbort ()
@@ -217,7 +225,7 @@ namespace System.ServiceModel
                }
 
                public Uri ListenUri {
-                       get { throw new NotImplementedException (); }
+                       get { return runtime.ChannelDispatcher.Listener.Uri; }
                }
 
                #region IDisposable Members
index d99044dbff47a6e3878ae9f5ad46e5980f728394..debb880c88dd86262ea751324153219c817ec6c3 100644 (file)
@@ -1,3 +1,7 @@
+2009-08-17  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * MessageTest.cs : added test for State.
+
 2009-06-08  Atsushi Enomoto  <atsushi@ximian.com>
 
        * CommunicationObjectTest.cs : added a couple of close/abort tests
index 880f70e09634e24480ada3a81f67e238802dfdb4..a54294c2674881acd397c1a4a715e8bff6987f60 100644 (file)
@@ -319,5 +319,16 @@ namespace MonoTests.System.ServiceModel.Channels
                        m = Message.CreateMessage (MessageVersion.Default, new FaultCode ("ActionNotSupported", "urn:myfault"), "I dunno", "urn:myaction");
                        Assert.IsTrue (m.IsFault, "#2");
                }
+
+               [Test]
+               public void State ()
+               {
+                       var msg = Message.CreateMessage (MessageVersion.Soap11, "urn:foo", (object) null);
+                       var xw = XmlDictionaryWriter.CreateDictionaryWriter (XmlWriter.Create (TextWriter.Null));
+                       msg.WriteStartEnvelope (xw);
+                       Assert.AreEqual (MessageState.Created, msg.State, "#1");
+                       msg.WriteStartBody (xw);
+                       Assert.AreEqual (MessageState.Created, msg.State, "#2");
+               }
        }
 }
diff --git a/mcs/class/System.Web.Extensions/System.Web.Configuration/ChangeLog b/mcs/class/System.Web.Extensions/System.Web.Configuration/ChangeLog
new file mode 100644 (file)
index 0000000..19e32d9
--- /dev/null
@@ -0,0 +1,5 @@
+2009-08-17  Marek Habersack  <mhabersack@novell.com>
+
+       * ScriptingJsonSerializationSection.cs: MaxJsonLength default
+       value is 2097152 for .NET 3.5+
+
index 9ee1775b5d2e1ce1b200df4810330882781607df..ab3009bc67aa5038b8e85f8ff820e70b52097c0c 100644 (file)
@@ -43,7 +43,11 @@ namespace System.Web.Configuration
                        }
                }
 
+#if NET_3_5
+               [ConfigurationPropertyAttribute ("maxJsonLength", DefaultValue = 2097152)]
+#else
                [ConfigurationPropertyAttribute ("maxJsonLength", DefaultValue = 102400)]
+#endif
                public int MaxJsonLength {
                        get {
                                return (int) this ["maxJsonLength"];
index 7b8511b93c66402ba02f1af74fddb80e6f665bf0..5cb604314f4fb3feb478275e061655d760b2c506 100644 (file)
@@ -1,3 +1,15 @@
+2009-08-18  Marek Habersack  <mhabersack@novell.com>
+
+       * JavaScriptSerializer.cs: read converters from the config only if
+       explicitly requested.
+
+2009-08-17  Marek Habersack  <mhabersack@novell.com>
+
+       * JsonSerializer.cs: serialize fields before properties.
+
+       * JavaScriptSerializer.cs: MaxJsonLength default value for .NET
+       3.5 is 2097152
+
 2009-03-17  Marek Habersack  <mhabersack@novell.com>
 
        * JavaScriptSerializer.cs: if conversion of IDictionary or
index b3847e34278b378b73b920e2b1e0032af02dabaa..7d2021dc3cef44cd9da510b697264798ed4a5aef 100644 (file)
@@ -49,28 +49,60 @@ namespace System.Web.Script.Serialization
                int _maxJsonLength;
                int _recursionLimit;
                JavaScriptTypeResolver _typeResolver;
-               internal static readonly JavaScriptSerializer DefaultSerializer = new JavaScriptSerializer ();
+               internal static readonly JavaScriptSerializer DefaultSerializer = new JavaScriptSerializer (null, false);
 
-               public JavaScriptSerializer () 
-                       : this(null)
+               public JavaScriptSerializer () : this (null, false)
                {
                }
 
-               public JavaScriptSerializer (JavaScriptTypeResolver resolver) 
+               public JavaScriptSerializer (JavaScriptTypeResolver resolver) : this (resolver, false)
+               {
+               }
+               
+               internal JavaScriptSerializer (JavaScriptTypeResolver resolver, bool registerConverters)
                {
                        _typeResolver = resolver;
 
                        ScriptingJsonSerializationSection section = (ScriptingJsonSerializationSection) ConfigurationManager.GetSection ("system.web.extensions/scripting/webServices/jsonSerialization");
                        if (section == null) {
+#if NET_3_5
+                               _maxJsonLength = 2097152;
+#else
                                _maxJsonLength = 102400;
+#endif
                                _recursionLimit = 100;
-                       }
-                       else {
+                       } else {
                                _maxJsonLength = section.MaxJsonLength;
                                _recursionLimit = section.RecursionLimit;
+
+                               if (registerConverters) {
+                                       ConvertersCollection converters = section.Converters;
+                                       if (converters != null && converters.Count > 0) {
+                                               var cvtlist = new List <JavaScriptConverter> ();
+                                               Type type;
+                                               string typeName;
+                                               JavaScriptConverter jsc;
+                                               
+                                               foreach (Converter cvt in converters) {
+                                                       typeName = cvt != null ? cvt.Type : null;
+                                                       if (typeName == null)
+                                                               continue;
+                                                       
+                                                       type = HttpApplication.LoadType (typeName, true);
+                                                       if (type == null || !typeof (JavaScriptConverter).IsAssignableFrom (type))
+                                                               continue;
+                                                       
+                                                       jsc = Activator.CreateInstance (type) as JavaScriptConverter;
+                                                       cvtlist.Add (jsc);
+                                               }
+                                       
+                                               RegisterConverters (cvtlist);
+                                       }
+                               }
                        }
                }
 
+               
                public int MaxJsonLength {
                        get {
                                return _maxJsonLength;
index e1f239e47c1cccb585a6ce811f1799f9967e4be1..c89d84261b8b2104e2d80b3bb8b1e4e03341241c 100644 (file)
@@ -240,6 +240,9 @@ namespace System.Web.Script.Serialization
                bool ShouldIgnoreMember (MemberInfo mi, out MethodInfo getMethod)
                {
                        getMethod = null;
+                       if (mi == null)
+                               return true;
+                       
                        if (mi.IsDefined (typeof (ScriptIgnoreAttribute), true))
                                return true;
                        
@@ -250,7 +253,7 @@ namespace System.Web.Script.Serialization
                        PropertyInfo pi = mi as PropertyInfo;
                        if (pi == null)
                                return true;
-
+                       
                        getMethod = pi.GetGetMethod ();
                        if (getMethod == null || getMethod.GetParameters ().Length > 0) {
                                getMethod = null;
@@ -302,13 +305,20 @@ namespace System.Web.Script.Serialization
                                }
                        }
 
-                       MemberInfo[] members = type.GetMembers (BindingFlags.Public | BindingFlags.Instance);
+                       SerializeMembers <FieldInfo> (type.GetFields (BindingFlags.Public | BindingFlags.Instance), obj, output, ref first);
+                       SerializeMembers <PropertyInfo> (type.GetProperties (BindingFlags.Public | BindingFlags.Instance), obj, output, ref first);
+
+                       StringBuilderExtensions.AppendCount (output, maxJsonLength, "}");
+               }
+
+               void SerializeMembers <T> (T[] members, object obj, StringBuilder output, ref bool first) where T: MemberInfo
+               {
                        MemberInfo member;
                        MethodInfo getMethod;
                        string name;
                        
-                       foreach (MemberInfo mi in members) {
-                               if (ShouldIgnoreMember (mi, out getMethod))
+                       foreach (T mi in members) {
+                               if (ShouldIgnoreMember (mi as MemberInfo, out getMethod))
                                        continue;
 
                                name = mi.Name;
@@ -321,8 +331,6 @@ namespace System.Web.Script.Serialization
                                if (first)
                                        first = false;
                        }
-
-                       StringBuilderExtensions.AppendCount (output, maxJsonLength, "}");
                }
                
                void SerializeEnumerable (StringBuilder output, IEnumerable enumerable)
index c96e6c341520c93ef721af2d3abaf70a5c81f301..8557911077afa1a49334d35fe762dcf7c5d05e9d 100644 (file)
@@ -1,3 +1,8 @@
+2009-08-15  Marek Habersack  <mhabersack@novell.com>
+
+       * LogicalTypeInfo.cs: make sure JavaScriptSerializer instance used
+       here reads custom converters from web.config. Fixes bug #525589
+
 2009-06-14  Robert Jordan  <robertj@gmx.net>
 
        * ScriptHandlerFactory.cs: handle precompiled web services.
index 2692c6eaaa7b9d891f027ca82c138c9ed9c8927e..4c301e6dd7e84c1a1b79c805de6456d6795043ad 100644 (file)
@@ -196,7 +196,7 @@ return this._invoke({0}.get_path(), '{1}',{2},{{{3}}},succeededCallback,failedCa
                readonly Hashtable _methodMap;
                readonly Type _type;
                readonly string _proxy;
-               static readonly JavaScriptSerializer JSSerializer = new JavaScriptSerializer ();
+               static readonly JavaScriptSerializer JSSerializer = new JavaScriptSerializer (null, true);
 
                private LogicalTypeInfo (Type t, string filePath) {
                        _type = t;
index f34b6c0c37331490b145303288efe31c183e335c..54c20f2ffeff925f3af2807ed7f30d0d287c395a 100644 (file)
@@ -1,3 +1,7 @@
+2009-08-17  Marek Habersack  <mhabersack@novell.com>
+
+       * JavaScriptSerializerTest.cs: fixed broken tests
+
 2009-06-18  Marek Habersack  <mhabersack@novell.com>
 
        * JavaScriptSerializerTest.cs: added comparison with the
index 1ead748a6a909f4323c960bf1e968c14ff2e76bc..e97be3b4e7670948d005c385765baff405db70fc 100644 (file)
@@ -347,7 +347,11 @@ namespace MonoTests.System.Web.Script.Serialization
                [Category ("NotDotNet")]
                public void TestDefaults () {
                        JavaScriptSerializer ser = new JavaScriptSerializer ();
+#if NET_3_5
+                       Assert.AreEqual (2097152, ser.MaxJsonLength);
+#else
                        Assert.AreEqual (102400, ser.MaxJsonLength);
+#endif
                        Assert.AreEqual (100, ser.RecursionLimit);
                        //List<JavaScriptConverter> l = new List<JavaScriptConverter> ();
                        //l.Add (new MyJavaScriptConverter ());
@@ -419,7 +423,6 @@ namespace MonoTests.System.Web.Script.Serialization
                        x.Init ();
 
                        string s = ser.Serialize (x);
-                       Console.WriteLine (s);
                        Assert.AreEqual ("{\"__type\":\"MonoTests.System.Web.Script.Serialization.JavaScriptSerializerTest+X, System.Web.Extensions_test_net_2_0, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\"z\":8,\"ch\":\"v\",\"ch_null\":null,\"str\":\"vwF59g\",\"b\":253,\"sb\":-48,\"sh\":-32740,\"ush\":65511,\"i\":-234235453,\"ui\":4294733061,\"l\":-9223372036854775780,\"ul\":18446744073709551612,\"f\":NaN,\"f1\":-Infinity,\"f2\":Infinity,\"f3\":-3.40282347E+38,\"f4\":3.40282347E+38,\"d\":NaN,\"d1\":-Infinity,\"d2\":Infinity,\"d3\":-1.7976931348623157E+308,\"d4\":1.7976931348623157E+308,\"de\":-1,\"de1\":0,\"de2\":1,\"de3\":-79228162514264337593543950335,\"de4\":79228162514264337593543950335,\"g\":\"000000ea-0002-0162-0102-030405060708\",\"nb\":null,\"dbn\":null,\"uri\":\"http://kostat@mainsoft/adfasdf/asdfasdf.aspx/asda/ads?a=b&c=d\",\"hash\":{\"mykey\":{\"__type\":\"MonoTests.System.Web.Script.Serialization.JavaScriptSerializerTest+Y, System.Web.Extensions_test_net_2_0, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\"BB\":10}},\"point\":{\"__type\":\"System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\",\"IsEmpty\":false,\"X\":150,\"Y\":150},\"MyEnum\":[1,10,345],\"MyEnum1\":[1,10,345],\"AA\":5,\"AA1\":[{\"__type\":\"MonoTests.System.Web.Script.Serialization.JavaScriptSerializerTest+Y, System.Web.Extensions_test_net_2_0, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\"BB\":10},{\"__type\":\"MonoTests.System.Web.Script.Serialization.JavaScriptSerializerTest+Y, System.Web.Extensions_test_net_2_0, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\"BB\":10}],\"BB\":18446744073709551610,\"YY\":[{\"__type\":\"MonoTests.System.Web.Script.Serialization.JavaScriptSerializerTest+Y, System.Web.Extensions_test_net_2_0, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\"BB\":10},{\"__type\":\"MonoTests.System.Web.Script.Serialization.JavaScriptSerializerTest+Y, System.Web.Extensions_test_net_2_0, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\"BB\":10}]}", s, "#A1");
                        
                        X x2 = ser.Deserialize<X> (s);
index d43807a73cc31f4c2a8dc8d710ef930caf69896f..fc040dcd30bc880f73d65a4272c2cf86b15f8244 100644 (file)
@@ -1,3 +1,8 @@
+2009-08-13  Marek Habersack  <mhabersack@novell.com>
+
+       * Makefile: build only in the 2.0 profile, or otherwise we'll end
+       up with the resulting assembly referencing the 4.0 corlib.
+
 2009-04-21  Marek Habersack  <mhabersack@novell.com>
 
        * Makefile: fixed resource ID generation.
index 90bf95d9106a56cb452552c6de5da57ae7908082..eaabeb6efebb8fbfff0a363dfba2da72ec448fa3 100644 (file)
@@ -26,8 +26,8 @@ endif
 
 EXTRA_DISTFILES = $(RESX_DIST)
 
-# This is a .NET 3.5+ assembly
-VALID_PROFILE := $(filter net_2_0 net_4_0, $(PROFILE))
+# This is a .NET 3.5+ assembly - it must be built ONLY in the 2.0 profile
+VALID_PROFILE := $(filter net_2_0, $(PROFILE))
 ifndef VALID_PROFILE
 LIBRARY_NAME = dummy-System.Web.Mvc.dll
 NO_INSTALL = yes
index 54287ab63b2bec62d382f65a18c55105eda0419b..2063013abe17b7fa1d64b66752ad74333391a65b 100644 (file)
@@ -1,3 +1,13 @@
+2009-08-18  Marek Habersack  <mhabersack@novell.com>
+
+       * Makefile (TEST_RESOURCE_FILES): added
+       Test/mainsoft/NunitWebResources/DuplicateControlsInClientComment.aspx
+
+2009-08-15  Marek Habersack  <mhabersack@novell.com>
+
+       * Makefile (TEST_RESOURCE_FILES): added
+       Test/mainsoft/NunitWebResources/NewlineInCodeExpression.aspx
+
 2009-07-30  Raja R Harinath  <harinath@hurrynot.org>
 
        * Makefile ($(build_lib)): Move cyclic dependencies onto this.
index 10e2d8adff144133be267f9d0ba879fead053e21..af8857dc5e576e623b586f7b3c4957da4e8b1cfe 100644 (file)
@@ -76,7 +76,6 @@ RESOURCE_FILES_2 = \
 OTHER_RES = $(RESOURCE_FILES_1)
 TEST_RESOURCE_FILES = \
        Test/mainsoft/NunitWeb/NunitWeb/Resources/Global.asax \
-       Test/mainsoft/NunitWeb/NunitWeb/Resources/Global.asax.cs \
        Test/mainsoft/NunitWeb/NunitWeb/Resources/My.ashx \
        Test/mainsoft/NunitWeb/NunitWeb/Resources/My.master \
        Test/mainsoft/NunitWeb/NunitWeb/Resources/MyPage.aspx \
@@ -174,7 +173,9 @@ TEST_RESOURCE_FILES = \
        Test/mainsoft/NunitWebResources/PreprocessorDirectivesInMarkup.aspx \
        Test/mainsoft/NunitWebResources/UnquotedAngleBrackets.aspx \
        Test/mainsoft/NunitWebResources/FullTagsInText.aspx \
-       Test/mainsoft/NunitWebResources/TagsExpressionsAndCommentsInText.aspx
+       Test/mainsoft/NunitWebResources/TagsExpressionsAndCommentsInText.aspx \
+       Test/mainsoft/NunitWebResources/NewlineInCodeExpression.aspx \
+       Test/mainsoft/NunitWebResources/DuplicateControlsInClientComment.aspx
 
 RESX_DIST =  resources/TranslationResources.resx
 ifneq (1, $(FRAMEWORK_VERSION_MAJOR))
index 9a566676810a9c7c1e5546b6a1796dc4dabed307..b29dc60746dbec632a3b9168989e657e97f1646b 100644 (file)
@@ -3,9 +3,10 @@
 //
 // Authors:
 //     Gonzalo Paniagua Javier (gonzalo@ximian.com)
+//      Marek Habersack <mhabersack@novell.com>
 //
 // (C) 2002,2003 Ximian, Inc (http://www.ximian.com)
-// Copyright (c) 2004,2006 Novell, Inc (http://www.novell.com)
+// Copyright (c) 2004-2009 Novell, Inc (http://www.novell.com)
 //
 
 //
@@ -56,7 +57,7 @@ namespace System.Web.Compilation
                public BuilderLocation (ControlBuilder builder, ILocation location)
                {
                        this.Builder = builder;
-                       this.Location = location;
+                       this.Location = new Location (location);
                }
        }
 
@@ -181,6 +182,33 @@ namespace System.Web.Compilation
                }
        }
 
+       enum TextBlockType
+       {
+               Verbatim,
+               Expression,
+               Tag,
+               Comment
+       }
+       
+       sealed class TextBlock
+       {
+               public string Content;
+               public readonly TextBlockType Type;
+               public readonly int Length;
+               
+               public TextBlock (TextBlockType type, string content)
+               {
+                       Content = content;
+                       Type = type;
+                       Length = content.Length;
+               }
+
+               public override string ToString ()
+               {
+                       return this.GetType ().FullName + " [" + this.Type + "]";
+               }
+       }
+       
        class AspGenerator
        {
 #if NET_2_0
@@ -188,6 +216,25 @@ namespace System.Web.Compilation
                
                internal static Regex DirectiveRegex = new Regex (@"<%\s*@(\s*(?<attrname>\w[\w:]*(?=\W))(\s*(?<equal>=)\s*""(?<attrval>[^""]*)""|\s*(?<equal>=)\s*'(?<attrval>[^']*)'|\s*(?<equal>=)\s*(?<attrval>[^\s%>]*)|(?<equal>)(?<attrval>\s*?)))*\s*?%>", RegexOptions.Compiled | RegexOptions.IgnoreCase);
 #endif
+               static readonly Regex runatServer = new Regex (@"<[\w:\.]+.*?runat=[""']?server[""']?.*?/?>",
+                                                              RegexOptions.Compiled | RegexOptions.Singleline |
+                                                              RegexOptions.Multiline | RegexOptions.IgnoreCase |
+                                                              RegexOptions.CultureInvariant);
+               
+               static readonly Regex endOfTag = new Regex (@"</[\w:\.]+\s*?>",
+                                                           RegexOptions.Compiled | RegexOptions.Singleline |
+                                                           RegexOptions.Multiline | RegexOptions.IgnoreCase |
+                                                           RegexOptions.CultureInvariant);
+               
+               static readonly Regex expressionRegex = new Regex (@"<%.*?%>",
+                                                                  RegexOptions.Compiled | RegexOptions.Singleline |
+                                                                  RegexOptions.Multiline | RegexOptions.IgnoreCase |
+                                                                  RegexOptions.CultureInvariant);
+
+               static readonly Regex clientCommentRegex = new Regex (@"<!--(.|\s)*?-->",
+                                                                     RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.IgnoreCase |
+                                                                     RegexOptions.CultureInvariant);
+               
                ParserStack pstack;
                BuilderLocationStack stack;
                TemplateParser tparser;
@@ -702,8 +749,15 @@ namespace System.Web.Compilation
                                return type;
                        }
 
+#if NET_2_0
                        Parse ();
-
+#else
+                       try {
+                               Parse ();
+                       } catch (ParseException ex) {
+                               throw new HttpException ("Compilation failed.", ex);
+                       }
+#endif
                        BaseCompiler compiler = GetCompilerFromType ();
                        
                        type = compiler.GetCompiledType ();
@@ -757,10 +811,6 @@ namespace System.Web.Compilation
                // The kludge supports only self-closing tags inside attributes.
                //
                // KLUDGE WARNING!!
-               static readonly Regex runatServer=new Regex (@"<[\w:\.]+.*?runat=[""']?server[""']?.*?/>",
-                                                            RegexOptions.Compiled | RegexOptions.Singleline |
-                                                            RegexOptions.Multiline | RegexOptions.IgnoreCase |
-                                                            RegexOptions.CultureInvariant);
                bool ProcessTagsInAttributes (ILocation location, string tagid, TagAttributes attributes, TagType type)
                {
                        if (attributes == null || attributes.Count == 0)
@@ -798,7 +848,7 @@ namespace System.Web.Compilation
 
                                TextParsed (location, String.Format (" {0}=\"{1}", key, index > 0 ? value.Substring (0, index) : String.Empty));;
                                FlushText ();
-                               ParseAttributeTag (group.Value);
+                               ParseAttributeTag (group.Value, location);
                                if (index + length < value.Length)
                                        TextParsed (location, value.Substring (index + length) + "\"");
                                else
@@ -815,9 +865,9 @@ namespace System.Web.Compilation
                        return retval;
                }
 
-               void ParseAttributeTag (string code)
+               void ParseAttributeTag (string code, ILocation location)
                {
-                       AspParser parser = new AspParser ("@@attribute_tag@@", new StringReader (code));
+                       AspParser parser = new AspParser ("@@attribute_tag@@", new StringReader (code), location.BeginLine - 1, location as AspParser);
                        parser.Error += new ParseErrorHandler (ParseError);
                        parser.TagParsed += new TagParsedHandler (TagParsed);
                        parser.TextParsed += new TextParsedHandler (TextParsed);
@@ -1006,118 +1056,127 @@ namespace System.Web.Compilation
 
                        return Path.GetFullPath (Path.Combine (basedir, filename));
                }
+
+               delegate bool CheckBlockEnd (string text);
                
-               void TextParsed (ILocation location, string text)
+               bool CheckTagEndNeeded (string text)
                {
-                       if (ignore_text)
-                               return;
-                       
-                       // Another gross hack - get rid of comments in the parsed text
-                       int textLen = text.Length;
-                       int textMaxIndex = textLen - 1;
-                       int commentStart = text.IndexOf ("<!--");
-                       int commentLastStart = 0;
+                       return !text.EndsWith ("/>");
+               }
+               
 #if NET_2_0
-                       List <int> commentRanges = null;
+               List <TextBlock>
 #else
-                       ArrayList commentRanges = null;
+               ArrayList
 #endif
-
-                       while (commentStart != -1) {
-                               int commentEnd = text.IndexOf ("-->", commentStart);
-
-                               if (commentEnd == -1) {
-                                       if (commentStart == 0)
-                                               return;
-                                       commentEnd = textMaxIndex;
-                               }
-
-                               if (commentRanges == null) {
+               FindRegexBlocks (Regex rxStart, Regex rxEnd, CheckBlockEnd checkEnd, IList blocks, TextBlockType typeForMatches, bool discardBlocks)
+               {
 #if NET_2_0
-                                       commentRanges = new List <int> ();
+                       var ret = new List <TextBlock> ();
 #else
-                                       commentRanges = new ArrayList ();
+                       ArrayList ret = new ArrayList ();
 #endif
+                       
+                       foreach (TextBlock block in blocks) {
+                               if (block.Type != TextBlockType.Verbatim) {
+                                       ret.Add (block);
+                                       continue;
                                }
 
-                               if (commentStart > commentLastStart) {
-                                       commentRanges.Add (commentLastStart);
-                                       commentRanges.Add (commentStart);
-                               }
+                               int lastIndex = 0, index;
+                               MatchCollection matches = rxStart.Matches (block.Content);
+                               bool foundMatches = matches.Count > 0;
+                               foreach (Match match in matches) {
+                                       foundMatches = true;
+                                       index = match.Index;
+                                       if (lastIndex < index)
+                                               ret.Add (new TextBlock (TextBlockType.Verbatim, block.Content.Substring (lastIndex, index - lastIndex)));
 
-                               if (commentEnd == textMaxIndex)
-                                       break;
-                               
-                               commentLastStart = commentEnd + 3;
-                               if (commentLastStart > textMaxIndex)
-                                       break;
-                               
-                               commentStart = text.IndexOf ("<!--", commentLastStart);
-                               if (commentStart == -1) {
-                                       int tailLength = textMaxIndex - commentLastStart;
-                                       if (tailLength > 0) {
-                                               commentRanges.Add (commentLastStart);
-                                               commentRanges.Add (tailLength);
+                                       string value = match.Value;
+                                       if (rxEnd != null && checkEnd (value)) {
+                                               int startFrom = index + value.Length;
+                                               Match m = rxEnd.Match (block.Content, startFrom);
+                                               if (m.Success)
+                                                       value += block.Content.Substring (startFrom, m.Index - startFrom) + m.Value;
                                        }
-                                       break;
+
+                                       if (!discardBlocks)
+                                               ret.Add (new TextBlock (typeForMatches, value));
+                                       lastIndex = index + value.Length;
                                }
+
+                               if (lastIndex > 0 && lastIndex < block.Content.Length)
+                                       ret.Add (new TextBlock (TextBlockType.Verbatim, block.Content.Substring (lastIndex)));
+
+                               if (!foundMatches)
+                                       ret.Add (block);
                        }
 
-                       if (commentRanges != null) {
-                               if (commentRanges.Count == 0)
-                                       return;
-                               
-                               StringBuilder sb = new StringBuilder ();
-                               for (int i = 0; i < commentRanges.Count; i += 2) {
+                       return ret;
+               }
+               
+               IList SplitTextIntoBlocks (string text)
+               {
 #if NET_2_0
-                                       sb.Append (text.Substring (commentRanges [i], commentRanges [i + 1]));
+                       var ret = new List <TextBlock> ();
 #else
-                                       sb.Append (text.Substring ((int)commentRanges [i], (int)commentRanges [i + 1]));
+                       ArrayList ret = new ArrayList ();
 #endif
-                               }
 
-                               string noComments = sb.ToString ().Trim ();
-                               if (noComments.Length == 0)
-                                       return;
+                       ret.Add (new TextBlock (TextBlockType.Verbatim, text));
+                       ret = FindRegexBlocks (clientCommentRegex, null, null, ret, TextBlockType.Comment, false);
+                       ret = FindRegexBlocks (runatServer, endOfTag, CheckTagEndNeeded, ret, TextBlockType.Tag, false);
+                       ret = FindRegexBlocks (expressionRegex, null, null, ret, TextBlockType.Expression, false);
 
-                               text = noComments;
-                       }
+                       return ret;
+               }
 
-                       // And again... the first one wins - if we have expressions and server-side
-                       // controls together in one block of plain text, tough luck...
-                       if (text.IndexOf ("<%") != -1 && !inScript) {
-                               if (this.text.Length > 0)
-                                       FlushText (true);
-                               CodeRenderParser r = new CodeRenderParser (text, stack.Builder);
-                               r.AddChildren (this);
+               void TextParsed (ILocation location, string text)
+               {
+                       if (ignore_text)
+                               return;
+
+                       if (inScript) {
+                               this.text.Append (text);
+                               FlushText (true);
                                return;
                        }
+                       
+                       IList blocks = SplitTextIntoBlocks (text);
+                       foreach (TextBlock block in blocks) {
+                               switch (block.Type) {
+                                       case TextBlockType.Verbatim:
+                                               this.text.Append (block.Content);
+                                               break;
 
-                       int startIndex = 0, index = 0;
-                       Match match;
+                                       case TextBlockType.Expression:
+                                               if (this.text.Length > 0)
+                                                       FlushText (true);
+                                               CodeRenderParser r = new CodeRenderParser (block.Content, stack.Builder, location);
+                                               r.AddChildren (this);
+                                               break;
 
-                       while (index > -1 && startIndex < textLen) {
-                               match = runatServer.Match (text, index);
-                                       
-                               if (match.Success) {
-                                       string value = match.Value;
-                                       index = match.Index;
-                                       if (index > startIndex)
-                                               this.text.Append (text.Substring (startIndex, index - startIndex));
-                                       ParseAttributeTag (value);
-                                       index += value.Length;
-                                       startIndex = index;
-                               } else
-                                       break;
+                                       case TextBlockType.Tag:
+                                               ParseAttributeTag (block.Content, location);
+                                               break;
 
-                               if (index < textLen)
-                                       index = text.IndexOf ('<', index);
-                               else
-                                       break;
+                                       case TextBlockType.Comment: {
+                                               this.text.Append ("<!--");
+                                               FlushText (true);
+                                               AspParser parser = new AspParser ("@@comment_code@@",
+                                                                                 new StringReader (block.Content.Substring (4, block.Length - 7)),
+                                                                                 location.BeginLine - 1,
+                                                                                 location as AspParser);
+                                               parser.Error += new ParseErrorHandler (ParseError);
+                                               parser.TagParsed += new TagParsedHandler (TagParsed);
+                                               parser.TextParsed += new TextParsedHandler (TextParsed);
+                                               parser.Parse ();
+                                               this.text.Append ("-->");
+                                               FlushText (true);
+                                               break;
+                                       }
+                               }
                        }
-                       
-                       this.text.Append (text.Substring (startIndex));
-                       //PrintLocation (location);
                }
 
                void FlushText ()
@@ -1331,7 +1390,7 @@ namespace System.Web.Compilation
                                        CheckLanguage (language);
                                        string src = (string) attributes ["src"];
                                        if (src != null) {
-                                               if (src == "")
+                                               if (src.Length == 0)
                                                        throw new ParseException (Parser,
                                                                "src cannot be an empty string");
 
@@ -1498,11 +1557,13 @@ namespace System.Web.Compilation
                        string str;
                        ControlBuilder builder;
                        AspGenerator generator;
+                       ILocation location;
                        
-                       public CodeRenderParser (string str, ControlBuilder builder)
+                       public CodeRenderParser (string str, ControlBuilder builder, ILocation location)
                        {
                                this.str = str;
                                this.builder = builder;
+                               this.location = location;
                        }
 
                        public void AddChildren (AspGenerator generator)
@@ -1518,7 +1579,7 @@ namespace System.Web.Compilation
                        void DoParseExpressions (string str)
                        {
                                int startIndex = 0, index = 0;
-                               Regex codeDirective = new Regex ("(<%(?!@)(?<code>.*?)%>)|(<[\\w:\\.]+.*?runat=[\"']?server[\"']?.*?/>)",
+                               Regex codeDirective = new Regex ("(<%(?!@)(?<code>(.|\\s)*?)%>)|(<[\\w:\\.]+.*?runat=[\"']?server[\"']?.*?/>)",
                                                                 RegexOptions.Multiline | RegexOptions.Compiled | RegexOptions.CultureInvariant);
                                Match match;
                                int strLen = str.Length;
@@ -1549,7 +1610,7 @@ namespace System.Web.Compilation
                        
                        void DoParse (string str)
                        {
-                               AspParser parser = new AspParser ("@@nested_tag@@", new StringReader (str));
+                               AspParser parser = new AspParser ("@@code_render@@", new StringReader (str), location.BeginLine - 1, location as AspParser);
                                parser.Error += new ParseErrorHandler (ParseError);
                                parser.TagParsed += new TagParsedHandler (TagParsed);
                                parser.TextParsed += new TextParsedHandler (TextParsed);
index cc706f8185e7e0660c3d6ec6064a458fcfd2340d..2f7398477bc5f839ba0fa20616bbd789e1468d12 100644 (file)
@@ -65,6 +65,9 @@ namespace System.Web.Compilation
                string verbatimID;
                string fileText;
                StringReader fileReader;
+               bool _internal;
+               int _internalLineOffset;
+               AspParser outer;
                
                EventHandlerList events = new EventHandlerList ();
                
@@ -95,9 +98,18 @@ namespace System.Web.Compilation
                        this.filename = filename;
                        this.fileText = input.ReadToEnd ();
                        this.fileReader = new StringReader (this.fileText);
+                       this._internalLineOffset = 0;
                        tokenizer = new AspTokenizer (this.fileReader);
                }
 
+               public AspParser (string filename, TextReader input, int startLineOffset, AspParser outer)
+                       : this (filename, input)
+               {
+                       this._internal = true;
+                       this._internalLineOffset = startLineOffset;
+                       this.outer = outer;
+               }
+               
 #if NET_2_0
                public byte[] MD5Checksum {
                        get {
@@ -110,7 +122,12 @@ namespace System.Web.Compilation
 #endif
                
                public int BeginLine {
-                       get { return beginLine; }
+                       get {
+                               if (Internal)
+                                       return beginLine + InternalLineOffset;
+
+                               return beginLine;
+                       }
                }
 
                public int BeginColumn {
@@ -118,19 +135,38 @@ namespace System.Web.Compilation
                }
 
                public int EndLine {
-                       get { return endLine; }
+                       get {
+                               if (Internal)
+                                       return endLine + InternalLineOffset;
+                               return endLine;
+                       }
                }
 
                public int EndColumn {
                        get { return endColumn; }
                }
 
+               public bool Internal {
+                       get { return _internal; }
+                       set { _internal = value; }
+               }
+
+               public int InternalLineOffset {
+                       get { return _internalLineOffset; }
+                       set { _internalLineOffset = value; }
+               }
+               
                public string FileText {
                        get {
-                               if (fileText != null)
-                                       return fileText;
+                               string ret = null;
                                
-                               return null;
+                               if (Internal && outer != null)
+                                       ret = outer.FileText;
+                               
+                               if (ret == null && fileText != null)
+                                       ret = fileText;
+                               
+                               return ret;
                        }
                }
                
@@ -139,12 +175,31 @@ namespace System.Web.Compilation
                                if (beginPosition >= endPosition || fileText == null)
                                        return null;
 
-                               return fileText.Substring (beginPosition, endPosition - beginPosition);
+                               string text = FileText;
+                               int start, len;
+                               
+                               if (Internal && outer != null) {
+                                       start = beginPosition + InternalLineOffset;
+                                       len = (endPosition + InternalLineOffset) - start;
+                               } else {
+                                       start = beginPosition;
+                                       len = endPosition - beginPosition;
+                               }
+                               
+                               if (text != null)
+                                       return text.Substring (start, len);
+
+                               return null;
                        }
                }
 
                public string Filename {
-                       get { return filename; }
+                       get {
+                               if (Internal && outer != null)
+                                       return outer.Filename;
+                               
+                               return filename;
+                       }
                }
 
                public string VerbatimID {
index 4e9e7f6759c154426f4691b3a2c07396bca694cc..b804084dbac1c2b3456b3eece5bb412ca47aa677 100644 (file)
@@ -119,10 +119,12 @@ namespace System.Web.Compilation
                                var cache = new Dictionary <string, bool> (dictionaryComparer);
                                AddVirtualDir (GetVirtualDirectory (virtualPath.Absolute), bpcoll, cache);
                                cache = null;
+                               if (buildProviders == null || buildProviders.Count == 0)
+                                       AddVirtualFile (GetVirtualFile (virtualPath.Absolute), bpcoll);
                        }
 
                        if (buildProviders == null || buildProviders.Count == 0)
-                               return null;
+                                       return null;
                        
                        var buildProviderGroups = new List <BuildProviderGroup> ();
                        foreach (BuildProvider bp in buildProviders.Values)
@@ -236,7 +238,7 @@ namespace System.Web.Compilation
                {
                        if (!vpp.DirectoryExists (VirtualPathUtility.GetDirectory (virtualPath)))
                                return null;
-                       
+
                        return vpp.GetDirectory (virtualPath);
                }
 
index 83cd6de9fce549811611f91b5f1540c6568a5639..0e1b2ecdd7ba2fdae1e0867674089ba4c6ad9b2e 100644 (file)
@@ -1,3 +1,34 @@
+2009-08-18  Marek Habersack  <mhabersack@novell.com>
+
+       * AspParser.cs: added a constructor which creates an internal
+       parser, nested within the outer one, and adjusts its ILocation
+       members to report correct locations in the outer parser for better
+       error reporting. Inner parser also returns the outer's FileText,
+       if available.
+
+       * AspGenerator.cs: restored part of r138474 reverted in r138657,
+       r138658 and r138659 to fix bug #525104
+       BuilderLocation creates a copy of Location for its own use (since
+       the ILocation passed is actually AspParser, the line numbers
+       change between creating a BuilderLocation and using its Location
+       member).
+       The end of tag, expression and client comment regular expressions
+       now use lazy quantifiers. This fixes bugs #525104 and #517656
+       Client side comment blocks aren't ignored anymore, they are parsed
+       just as the other parts of the document. Fixes bug #524358
+       
+2009-08-15  Marek Habersack  <mhabersack@novell.com>
+
+       * AspGenerator.cs: CodeRenderParser.DoParseExpressions - match
+       newline characters inside expressions. Fixes bug #526449
+
+2009-08-14  Marek Habersack  <mhabersack@novell.com>
+
+       * BuildManagerDirectoryBuilder.cs: when VirtualPathProvider
+       reports a virtual directory doesn't exist, try to get the
+       requested virtual path using VirtualPathProvider.GetFile. Fixes
+       #525974
+
 2009-07-30 Gonzalo Paniagua Javier <gonzalo@novell.com>
 
        * BuildManager.cs: path fixup should work now for /foo running on
index 343962f04c17ea4719c2931c03569d047e25f7b4..63d52d8dd99af50d22bd068902b9677b513340a1 100644 (file)
@@ -1,3 +1,17 @@
+2009-08-18  Marek Habersack  <mhabersack@novell.com>
+
+       * ControlBuilder.cs: Location property makes a copy of assigned
+       ILocation now.
+
+2009-08-14  Marek Habersack  <mhabersack@novell.com>
+
+       * ControlBuilder.cs: when CreateSubBuilder is called on a builder
+       which is supposed to treat its children as properties and the
+       default property builder is defined, first check if the tag which
+       has just been parsed isn't a template property. If it is, don't
+       use the default property builder, instead create a template
+       property builder directly. Fixes bug #527753
+
 2009-07-23  Marek Habersack  <mhabersack@novell.com>
 
        * ControlBuilder.cs: added an internal helper property
index 16aac32f6eb1cc8d2c9e7cf205be787c325b9af7..c84049d6de699ebe62bec91563800734a7569a02 100644 (file)
@@ -39,6 +39,8 @@ using System.Web.Configuration;
 using System.IO;
 using System.Web.UI.WebControls;
 
+using _Location = System.Web.Compilation.Location;
+
 namespace System.Web.UI {
 
        // CAS
@@ -169,7 +171,7 @@ namespace System.Web.UI {
 
                internal ILocation Location {
                        get { return location; }
-                       set { location = value; }
+                       set { location = new _Location (value); }
                }
        
                internal ArrayList OtherTags {
@@ -634,7 +636,7 @@ namespace System.Web.UI {
                {
                        this.parser = parser;
                        if (parser != null)
-                               this.location = parser.Location;
+                               this.Location = parser.Location;
 
                        this.parentBuilder = parentBuilder;
                        this.type = type;
@@ -710,10 +712,17 @@ namespace System.Web.UI {
                                                // builder call.
                                                defaultPropertyBuilder = null;
                                                childBuilder = CreatePropertyBuilder (tagid, parser, atts);
-                                       } else
-                                               childBuilder = defaultPropertyBuilder.CreateSubBuilder (tagid, atts,
-                                                                                                       null, parser,
-                                                                                                       location);
+                                       } else {
+                                               Type ct = ControlType;
+                                               MemberInfo[] mems = ct != null ? ct.GetMember (tagid, MemberTypes.Property, FlagsNoCase) : null;
+                                               PropertyInfo prop = mems != null && mems.Length > 0 ? mems [0] as PropertyInfo : null;
+
+                                               if (prop != null && typeof (ITemplate).IsAssignableFrom (prop.PropertyType)) {
+                                                       childBuilder = CreatePropertyBuilder (tagid, parser, atts);
+                                                       defaultPropertyBuilder = null;
+                                               } else
+                                                       childBuilder = defaultPropertyBuilder.CreateSubBuilder (tagid, atts, null, parser, location);
+                                       }
                                }
 
                                return childBuilder;
index 32637f2cdbd8460b0ba2cf43f06928a7a06b774a..c28a26b87ab01ed95787ae6ce1688febcff46d2b 100644 (file)
@@ -20,6 +20,7 @@ mainsoft/NunitWeb/NunitWeb/BaseWorkerRequest.cs
 mainsoft/NunitWeb/NunitWeb/CustomSection.cs
 mainsoft/NunitWeb/NunitWeb/FakeMembershipProvider.cs
 mainsoft/NunitWeb/NunitWeb/FormRequest.cs
+mainsoft/NunitWeb/NunitWeb/Global.asax.cs
 mainsoft/NunitWeb/NunitWeb/IForeignData.cs
 mainsoft/NunitWeb/NunitWeb/HandlerInvoker.cs
 mainsoft/NunitWeb/NunitWeb/MyHandler.cs
index 97d16cbf2188fa4ae6982530a21bbcc6f102b5d2..bbeaf758f74b35333c872325ac007e221dde2485 100644 (file)
@@ -1,3 +1,8 @@
+2009-08-18  Marek Habersack  <mhabersack@novell.com>
+
+       * TemplateControlCompilerTest.cs: added test for bug #525104 and
+       improved test for bug #517656
+
 2009-07-08  Marek Habersack  <mhabersack@novell.com>
 
        * TemplateControlCompilerTest.cs: added test for bug #520024
index 961dc780062e5ea3bfa97bf5c30300c9e6f7e44c..8d4b331560e9abd9d2eeb71d83d0f772e3f653ad 100644 (file)
@@ -58,6 +58,8 @@ namespace MonoTests.System.Web.Compilation {
                        WebTest.CopyResource (GetType (), "UnquotedAngleBrackets.aspx", "UnquotedAngleBrackets.aspx");
                        WebTest.CopyResource (GetType (), "FullTagsInText.aspx", "FullTagsInText.aspx");
                        WebTest.CopyResource (GetType (), "TagsExpressionsAndCommentsInText.aspx", "TagsExpressionsAndCommentsInText.aspx");
+                       WebTest.CopyResource (GetType (), "NewlineInCodeExpression.aspx", "NewlineInCodeExpression.aspx");
+                       WebTest.CopyResource (GetType (), "DuplicateControlsInClientComment.aspx", "DuplicateControlsInClientComment.aspx");
 #if NET_2_0
                        WebTest.CopyResource (GetType (), "InvalidPropertyBind1.aspx", "InvalidPropertyBind1.aspx");
                        WebTest.CopyResource (GetType (), "InvalidPropertyBind2.aspx", "InvalidPropertyBind2.aspx");
@@ -203,13 +205,34 @@ namespace MonoTests.System.Web.Compilation {
                        // Just test if it doesn't throw an exception
                        new WebTest ("PreprocessorDirectivesInMarkup.aspx").Run ();
                }
-#endif
 
+               [Test (Description="Bug #526449")]
+               public void NewlineInCodeExpression ()
+               {
+                       string pageHtml = new WebTest ("NewlineInCodeExpression.aspx").Run ();
+                       string renderedHtml = HtmlDiff.GetControlFromPageHtml (pageHtml);
+                       string originalHtml = "<a href=\"test\">bla</a>";
+                       HtmlDiff.AssertAreEqual (originalHtml, renderedHtml, "#A1");
+               }
+
+               [Test (Description="Bug #524358")]
+               [ExpectedException (typeof (HttpException))]
+               public void DuplicateControlsInClientComment ()
+               {
+                       // Just test if it throws an exception
+                       new WebTest ("DuplicateControlsInClientComment.aspx").Run ();
+               }
+#endif
+               
                [Test (Description="Bug #517656")]
                public void ServerControlInClientSideComment ()
                {
-                       // We just test if it doesn't throw an exception
-                       new WebTest ("ServerControlInClientSideComment.aspx").Run ();
+                       string pageHtml = new WebTest ("ServerControlInClientSideComment.aspx").Run ();
+                       string renderedHtml = HtmlDiff.GetControlFromPageHtml (pageHtml);
+                       string originalHtml = @"<!-- comment start
+  <input id=""testBox"" type=""checkbox"" name=""testBox"" />
+comment end -->";
+                       HtmlDiff.AssertAreEqual (originalHtml, renderedHtml, "#A1");
                }
 
                [Test]
diff --git a/mcs/class/System.Web/Test/mainsoft/NunitWeb/NunitWeb/Global.asax.cs b/mcs/class/System.Web/Test/mainsoft/NunitWeb/NunitWeb/Global.asax.cs
new file mode 100644 (file)
index 0000000..bd70928
--- /dev/null
@@ -0,0 +1,22 @@
+using System;\r
+\r
+namespace MainsoftWebApp\r
+{\r
+       public partial class Global : System.Web.HttpApplication\r
+       {\r
+#if NET_2_0\r
+               protected void Application_Error (object sender, EventArgs e)\r
+               {\r
+                       // Code that runs when an unhandled error occurs\r
+                       Exception objErr = Server.GetLastError ().GetBaseException ();\r
+                       MonoTests.SystemWeb.Framework.WebTest.RegisterException (objErr);\r
+                       Server.ClearError ();\r
+               }\r
+\r
+               protected void Application_OnEndRequest (object sender, EventArgs e) {\r
+                       // Ensure the headers are sent\r
+                       MonoTests.SystemWeb.Framework.WebTest.CurrentTest.SendHeaders ();\r
+               }\r
+#endif\r
+       }\r
+}\r
index bb6b26b484f97e73acd1ca53f6159392713ab3b2..ab0dba324411a130edb999a8bd5a758e54360c60 100644 (file)
@@ -1 +1 @@
-<%@ Application Language="C#" Inherits="MainsoftWebApp20.Global" CodeFile="Global.asax.cs" %>\r
+<%@ Application Language="C#" Inherits="MainsoftWebApp.Global" %>
diff --git a/mcs/class/System.Web/Test/mainsoft/NunitWeb/NunitWeb/Resources/Global.asax.cs b/mcs/class/System.Web/Test/mainsoft/NunitWeb/NunitWeb/Resources/Global.asax.cs
deleted file mode 100644 (file)
index 9ef7daa..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-using System;\r
-\r
-namespace MainsoftWebApp20\r
-{\r
-       public partial class Global : System.Web.HttpApplication\r
-       {\r
-               protected void Application_Error (object sender, EventArgs e)\r
-               {\r
-                       // Code that runs when an unhandled error occurs\r
-                       Exception objErr = Server.GetLastError ().GetBaseException ();\r
-                       MonoTests.SystemWeb.Framework.WebTest.RegisterException (objErr);\r
-                       Server.ClearError ();\r
-               }\r
-\r
-               protected void Application_OnEndRequest (object sender, EventArgs e) {\r
-                       // Ensure the headers are sent\r
-                       MonoTests.SystemWeb.Framework.WebTest.CurrentTest.SendHeaders ();\r
-               }\r
-       }\r
-}\r
diff --git a/mcs/class/System.Web/Test/mainsoft/NunitWebResources/DuplicateControlsInClientComment.aspx b/mcs/class/System.Web/Test/mainsoft/NunitWebResources/DuplicateControlsInClientComment.aspx
new file mode 100644 (file)
index 0000000..951c36c
--- /dev/null
@@ -0,0 +1,24 @@
+<%@ Page Language="C#" AutoEventWireup="true" %>
+
+<!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>
+    Hello World of mono lovers
+                <!--    <asp:Literal ID="form1" runat="server" />
+
+                        <br>                            -->
+    </div>
+    <asp:Repeater runat="server" id="r1">
+    <ItemTemplate>
+    <asp:Literal ID="form2" runat="server" />
+    </ItemTemplate>
+    </asp:Repeater>
+    </form>
+</body>
+</html>
diff --git a/mcs/class/System.Web/Test/mainsoft/NunitWebResources/NewlineInCodeExpression.aspx b/mcs/class/System.Web/Test/mainsoft/NunitWebResources/NewlineInCodeExpression.aspx
new file mode 100644 (file)
index 0000000..12c8965
--- /dev/null
@@ -0,0 +1,17 @@
+<%@ Page Language="C#" AutoEventWireup="true" %>
+
+<!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>
+    <%= MonoTests.stand_alone.WebHarness.HtmlDiff.BEGIN_TAG %><a href="<%= "test"
+        %>">bla</a><%= MonoTests.stand_alone.WebHarness.HtmlDiff.END_TAG %>
+    </div>
+    </form>
+</body>
+</html>
index 84d2f5bb502279a30e7891906d4be4afa7891996..e37928ee80393eb219f71746dc37f9cfb80b05eb 100644 (file)
@@ -1,6 +1,10 @@
 <%@ Page Language = "C#" %>
 
 <html><head><title>Bug 517656</title><head><body>
+<form runat="server">
+<%= MonoTests.stand_alone.WebHarness.HtmlDiff.BEGIN_TAG %><!-- comment start
+  <asp:Checkbox id="testBox" runat="server" />
+comment end --><%= MonoTests.stand_alone.WebHarness.HtmlDiff.END_TAG %>
 <p>ASP.NET repeater control to follow...</p>
 <asp:Repeater id="censusRepeater" runat="server">
        <HeaderTemplate />
@@ -33,4 +37,5 @@
        </ItemTemplate>
        <FooterTemplate />
 </asp:Repeater>
+</form>
 </body></html>
index 3c0da75d0d6a5372a83a3ea277628be5454f82e8..b0efa6bd38495db995b42b66d1b144bd085f9f0a 100644 (file)
@@ -1,3 +1,8 @@
+2009-08-11  Jérémie Laval  <jeremie.laval@gmail.com>
+
+       * System.dll.sources: Adding ParallelFx files.
+       * System_test.dll.sources: Adding ParallelFx test files.
+
 2009-07-26  Raja R Harinath  <harinath@hurrynot.org>
 
        * Makefile ($(build_lib)): Make CYCLIC_DEP_FILES depend on this.
index d3e411149221d5a0a9815450f69b8778e6a25ba3..e177ce13f28e04127c5b1725974efa053951c972 100644 (file)
@@ -1,3 +1,8 @@
+2009-08-13  Marek Habersack  <mhabersack@novell.com>
+
+       * CodeTypeReference.cs: generic types specialized on arrays must
+       not be treated as array declarations. Fixes bug #523341
+
 2008-02-10  Juraj Skripsky  <js@hotfeet.ch>
 
        * CodeObject.cs: Add empty Visit method implementation.
index 7478c356ce17722c4288d854ce9ad7b3df9fff5a..046ac907f43b800f85d41a893fa878d32a0fa59f 100644 (file)
@@ -210,6 +210,12 @@ namespace System.CodeDom
                                return;
                        }
 
+                       int lastAngle = baseType.LastIndexOf ('>');
+                       if (lastAngle != -1 && lastAngle > array_end) {
+                               this.baseType = baseType;
+                               return;
+                       }
+                       
                        string[] args = baseType.Substring (array_start + 1, array_end - array_start - 1).Split (',');
 
                        if ((array_end - array_start) != args.Length) {
diff --git a/mcs/class/System/System.Collections.Concurrent/BlockingCollection.cs b/mcs/class/System/System.Collections.Concurrent/BlockingCollection.cs
new file mode 100644 (file)
index 0000000..f3d1b4e
--- /dev/null
@@ -0,0 +1,552 @@
+#if NET_4_0
+// BlockingCollection.cs
+//
+// Copyright (c) 2008 Jérémie "Garuma" Laval
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+//
+
+using System;
+using System.Threading;
+using System.Collections;
+using System.Collections.Generic;
+using System.Diagnostics;
+
+namespace System.Collections.Concurrent
+{
+       public class BlockingCollection<T> : IEnumerable<T>, ICollection, IEnumerable, IDisposable
+       {
+               readonly IProducerConsumerCollection<T> underlyingColl;
+               readonly int upperBound;
+               
+               readonly SpinWait sw = new SpinWait ();
+               
+               AtomicBoolean isComplete;
+               long completeId;
+
+               long addId = long.MinValue;
+               long removeId = long.MinValue;
+               
+               #region ctors
+               public BlockingCollection ()
+                       : this (new ConcurrentQueue<T> (), -1)
+               {
+               }
+               
+               public BlockingCollection (int upperBound)
+                       : this (new ConcurrentQueue<T> (), upperBound)
+               {
+               }
+               
+               public BlockingCollection (IProducerConsumerCollection<T> underlyingColl)
+                       : this (underlyingColl, -1)
+               {
+               }
+               
+               public BlockingCollection (IProducerConsumerCollection<T> underlyingColl, int upperBound)
+               {
+                       this.underlyingColl = underlyingColl;
+                       this.upperBound     = upperBound;
+                       this.isComplete     = new AtomicBoolean ();
+               }
+               #endregion
+               
+               #region Add & Remove (+ Try)
+               public void Add (T item)
+               {
+                       Add (item, null);
+               }
+               
+               public void Add (T item, CancellationToken token)
+               {
+                       Add (item, () => token.IsCancellationRequested);
+               }
+               
+               void Add (T item, Func<bool> cancellationFunc)
+               {
+                       while (true) {
+                               long cachedAddId = addId;
+                               long cachedRemoveId = removeId;
+                               
+                               if (upperBound != -1) {
+                                       if (cachedAddId - cachedRemoveId > upperBound) {
+                                               Block ();
+                                               continue;
+                                       }
+                               }
+                               
+                               // Check our transaction id against completed stored one
+                               if (isComplete.Value && cachedAddId >= completeId)
+                                       throw new InvalidOperationException ("The BlockingCollection<T> has"
+                                                                            + " been marked as complete with regards to additions.");
+                               
+                               if (Interlocked.CompareExchange (ref addId, cachedAddId + 1, cachedAddId) == cachedAddId)
+                                       break;
+                               
+                               if (cancellationFunc != null && cancellationFunc ())
+                                       throw new OperationCanceledException ("CancellationToken triggered");
+                       }
+                       
+                       
+                       if (!underlyingColl.TryAdd (item))
+                               throw new InvalidOperationException ("The underlying collection didn't accept the item.");
+               }
+               
+               public T Take ()
+               {
+                       return Take (null);
+               }
+               
+               public T Take (CancellationToken token)
+               {
+                       return Take (() => token.IsCancellationRequested);
+               }
+               
+               T Take (Func<bool> cancellationFunc)
+               {
+                       while (true) {
+                               long cachedRemoveId = removeId;
+                               long cachedAddId = addId;
+                               
+                               // Empty case
+                               if (cachedRemoveId == cachedAddId) {
+                                       if (isComplete.Value && cachedRemoveId >= completeId)
+                                               throw new OperationCanceledException ("The BlockingCollection<T> has"
+                                                                                     + " been marked as complete with regards to additions.");
+                                       
+                                       Block ();
+                                       continue;
+                               }
+                               
+                               if (Interlocked.CompareExchange (ref removeId, cachedRemoveId + 1, cachedRemoveId) == cachedRemoveId)
+                                       break;
+                               
+                               if (cancellationFunc != null && cancellationFunc ())
+                                       throw new OperationCanceledException ("The CancellationToken has had cancellation requested.");
+                       }
+                       
+                       T item;
+                       while (!underlyingColl.TryTake (out item));
+                       
+                       return item;
+               }
+               
+               public bool TryAdd (T item)
+               {
+                       return TryAdd (item, null, null);
+               }
+               
+               bool TryAdd (T item, Func<bool> contFunc, CancellationToken? token)
+               {
+                       do {
+                               if (token.HasValue && token.Value.IsCancellationRequested)
+                                       throw new OperationCanceledException ("The CancellationToken has had cancellation requested.");
+                               
+                               long cachedAddId = addId;
+                               long cachedRemoveId = removeId;
+                               
+                               if (upperBound != -1) {
+                                       if (cachedAddId - cachedRemoveId > upperBound) {
+                                               continue;
+                                       }
+                               }
+                               
+                               // Check our transaction id against completed stored one
+                               if (isComplete.Value && cachedAddId >= completeId)
+                                       throw new InvalidOperationException ("The BlockingCollection<T> has"
+                                                                            + " been marked as complete with regards to additions.");
+                               
+                               if (Interlocked.CompareExchange (ref addId, cachedAddId + 1, cachedAddId) != cachedAddId)
+                                       continue;
+                       
+                               if (!underlyingColl.TryAdd (item))
+                                       throw new InvalidOperationException ("The underlying collection didn't accept the item.");
+                               
+                               return true;
+                       } while (contFunc != null && contFunc ());
+                       
+                       return false;
+               }
+               
+               public bool TryAdd (T item, TimeSpan ts)
+               {
+                       return TryAdd (item, (int)ts.TotalMilliseconds);
+               }
+               
+               public bool TryAdd (T item, int millisecondsTimeout)
+               {
+                       Stopwatch sw = Stopwatch.StartNew ();
+                       return TryAdd (item, () => sw.ElapsedMilliseconds < millisecondsTimeout, null);
+               }
+               
+               public bool TryAdd (T item, int millisecondsTimeout, CancellationToken token)
+               {
+                       Stopwatch sw = Stopwatch.StartNew ();
+                       return TryAdd (item, () => sw.ElapsedMilliseconds < millisecondsTimeout, token);
+               }
+               
+               public bool TryTake (out T item)
+               {
+                       return TryTake (out item, null, null);
+               }
+               
+               bool TryTake (out T item, Func<bool> contFunc, CancellationToken? token)
+               {
+                       item = default (T);
+                       
+                       do {
+                               if (token.HasValue && token.Value.IsCancellationRequested)
+                                       throw new OperationCanceledException ("The CancellationToken has had cancellation requested.");
+                               
+                               long cachedRemoveId = removeId;
+                               long cachedAddId = addId;
+                               
+                               // Empty case
+                               if (cachedRemoveId == cachedAddId) {
+                                       if (isComplete.Value && cachedRemoveId >= completeId)
+                                               continue;
+                                       
+                                       continue;
+                               }
+                               
+                               if (Interlocked.CompareExchange (ref removeId, cachedRemoveId + 1, cachedRemoveId) != cachedRemoveId)
+                                       continue;
+                               
+                               return underlyingColl.TryTake (out item);
+                       } while (contFunc != null && contFunc ());
+                       
+                       return false;
+               }
+               
+               public bool TryTake (out T item, TimeSpan ts)
+               {
+                       return TryTake (out item, (int)ts.TotalMilliseconds);
+               }
+               
+               public bool TryTake (out T item, int millisecondsTimeout)
+               {
+                       item = default (T);
+                       Stopwatch sw = Stopwatch.StartNew ();
+                       
+                       return TryTake (out item, () => sw.ElapsedMilliseconds < millisecondsTimeout, null);
+               }
+               
+               public bool TryTake (out T item, int millisecondsTimeout, CancellationToken token)
+               {
+                       item = default (T);
+                       Stopwatch sw = Stopwatch.StartNew ();
+                       
+                       return TryTake (out item, () => sw.ElapsedMilliseconds < millisecondsTimeout, token);
+               }
+               #endregion
+               
+               #region static methods
+               static void CheckArray (BlockingCollection<T>[] collections)
+               {
+                       if (collections == null)
+                               throw new ArgumentNullException ("collections");
+                       if (collections.Length == 0 || IsThereANullElement (collections))
+                               throw new ArgumentException ("The collections argument is a 0-length array or contains a null element.", "collections");
+               }
+               
+               static bool IsThereANullElement (BlockingCollection<T>[] collections)
+               {
+                       foreach (BlockingCollection<T> e in collections)
+                               if (e == null)
+                                       return true;
+                       return false;
+               }
+               
+               public static int AddToAny (BlockingCollection<T>[] collections, T item)
+               {
+                       CheckArray (collections);
+                       int index = 0;
+                       foreach (var coll in collections) {
+                               try {
+                                       coll.Add (item);
+                                       return index;
+                               } catch {}
+                               index++;
+                       }
+                       return -1;
+               }
+               
+               public static int AddToAny (BlockingCollection<T>[] collections, T item, CancellationToken token)
+               {
+                       CheckArray (collections);
+                       int index = 0;
+                       foreach (var coll in collections) {
+                               try {
+                                       coll.Add (item, token);
+                                       return index;
+                               } catch {}
+                               index++;
+                       }
+                       return -1;
+               }
+               
+               public static int TryAddToAny (BlockingCollection<T>[] collections, T item)
+               {
+                       CheckArray (collections);
+                       int index = 0;
+                       foreach (var coll in collections) {
+                               if (coll.TryAdd (item))
+                                       return index;
+                               index++;
+                       }
+                       return -1;
+               }
+               
+               public static int TryAddToAny (BlockingCollection<T>[] collections, T item, TimeSpan ts)
+               {
+                       CheckArray (collections);
+                       int index = 0;
+                       foreach (var coll in collections) {
+                               if (coll.TryAdd (item, ts))
+                                       return index;
+                               index++;
+                       }
+                       return -1;
+               }
+               
+               public static int TryAddToAny (BlockingCollection<T>[] collections, T item, int millisecondsTimeout)
+               {
+                       CheckArray (collections);
+                       int index = 0;
+                       foreach (var coll in collections) {
+                               if (coll.TryAdd (item, millisecondsTimeout))
+                                       return index;
+                               index++;
+                       }
+                       return -1;
+               }
+               
+               public static int TryAddToAny (BlockingCollection<T>[] collections, T item, int millisecondsTimeout,
+                                              CancellationToken token)
+               {
+                       CheckArray (collections);
+                       int index = 0;
+                       foreach (var coll in collections) {
+                               if (coll.TryAdd (item, millisecondsTimeout, token))
+                                       return index;
+                               index++;
+                       }
+                       return -1;
+               }
+               
+               public static int TakeFromAny (BlockingCollection<T>[] collections, out T item)
+               {
+                       item = default (T);
+                       CheckArray (collections);
+                       int index = 0;
+                       foreach (var coll in collections) {
+                               try {
+                                       item = coll.Take ();
+                                       return index;
+                               } catch {}
+                               index++;
+                       }
+                       return -1;
+               }
+               
+               public static int TakeFromAny (BlockingCollection<T>[] collections, out T item, CancellationToken token)
+               {
+                       item = default (T);
+                       CheckArray (collections);
+                       int index = 0;
+                       foreach (var coll in collections) {
+                               try {
+                                       item = coll.Take (token);
+                                       return index;
+                               } catch {}
+                               index++;
+                       }
+                       return -1;
+               }
+               
+               public static int TryTakeFromAny (BlockingCollection<T>[] collections, out T item)
+               {
+                       item = default (T);
+                       
+                       CheckArray (collections);
+                       int index = 0;
+                       foreach (var coll in collections) {
+                               if (coll.TryTake (out item))
+                                       return index;
+                               index++;
+                       }
+                       return -1;
+               }
+               
+               public static int TryTakeFromAny (BlockingCollection<T>[] collections, out T item, TimeSpan ts)
+               {
+                       item = default (T);
+                       
+                       CheckArray (collections);
+                       int index = 0;
+                       foreach (var coll in collections) {
+                               if (coll.TryTake (out item, ts))
+                                       return index;
+                               index++;
+                       }
+                       return -1;
+               }
+               
+               public static int TryTakeFromAny (BlockingCollection<T>[] collections, out T item, int millisecondsTimeout)
+               {
+                       item = default (T);
+                       
+                       CheckArray (collections);
+                       int index = 0;
+                       foreach (var coll in collections) {
+                               if (coll.TryTake (out item, millisecondsTimeout))
+                                       return index;
+                               index++;
+                       }
+                       return -1;
+               }
+               
+               public static int TryTakeFromAny (BlockingCollection<T>[] collections, out T item, int millisecondsTimeout,
+                                                 CancellationToken token)
+               {
+                       item = default (T);
+                       
+                       CheckArray (collections);
+                       int index = 0;
+                       foreach (var coll in collections) {
+                               if (coll.TryTake (out item, millisecondsTimeout, token))
+                                       return index;
+                               index++;
+                       }
+                       return -1;
+               }
+               #endregion
+               
+               public void CompleteAdding ()
+               {
+                 // No further add beside that point
+                 completeId = addId;
+                 isComplete.Value = true;
+               }
+               
+               void ICollection.CopyTo (Array array, int index)
+               {
+                       underlyingColl.CopyTo (array, index);
+               }
+               
+               public void CopyTo (T[] array, int index)
+               {
+                       underlyingColl.CopyTo (array, index);
+               }
+               
+               public IEnumerable<T> GetConsumingEnumerable ()
+               {
+                       return GetConsumingEnumerable (Take);
+               }
+               
+               public IEnumerable<T> GetConsumingEnumerable (CancellationToken token)
+               {
+                       return GetConsumingEnumerable (() => Take (token));
+               }
+               
+               IEnumerable<T> GetConsumingEnumerable (Func<T> getFunc)
+               {
+                       while (true) {
+                               T item = default (T);
+                               
+                               try {
+                                       item = getFunc ();
+                               } catch {
+                                       break;
+                               }
+                               
+                               yield return item;
+                       }
+               }
+               
+               IEnumerator IEnumerable.GetEnumerator ()
+               {
+                       return ((IEnumerable)underlyingColl).GetEnumerator ();
+               }
+               
+               IEnumerator<T> IEnumerable<T>.GetEnumerator ()
+               {
+                       return ((IEnumerable<T>)underlyingColl).GetEnumerator ();
+               }
+               
+               public void Dispose ()
+               {
+                       
+               }
+               
+               protected virtual void Dispose (bool managedRes)
+               {
+                       
+               }
+               
+               public T[] ToArray ()
+               {
+                       return underlyingColl.ToArray ();
+               }
+               
+               // Method used to stall the thread for a limited period of time before retrying an operation
+               void Block ()
+               {
+                       sw.SpinOnce ();
+               }
+               
+               public int BoundedCapacity {
+                       get {
+                               return upperBound;
+                       }
+               }
+               
+               public int Count {
+                       get {
+                               return underlyingColl.Count;
+                       }
+               }
+               
+               public bool IsAddingCompleted {
+                       get {
+                               return isComplete.Value;
+                       }
+               }
+               
+               public bool IsCompleted {
+                       get {
+                               return isComplete.Value && addId == removeId;
+                       }
+               }
+               
+               object ICollection.SyncRoot {
+                       get {
+                               return underlyingColl.SyncRoot;
+                       }
+               }
+               
+               bool ICollection.IsSynchronized {
+                       get {
+                               return underlyingColl.IsSynchronized;
+                       }
+               }
+       }
+}
+#endif
diff --git a/mcs/class/System/System.Collections.Concurrent/ChangeLog b/mcs/class/System/System.Collections.Concurrent/ChangeLog
new file mode 100644 (file)
index 0000000..2de71e8
--- /dev/null
@@ -0,0 +1,8 @@
+2009-08-19  Jérémie Laval  <jeremie.laval@gmail.com>
+
+       * BlockingCollection.cs: Rewrite to use a transaction id
+       based approach. Ported to 4.0 API. Fix GetConsumingEnumerable.
+
+2009-08-11  Jérémie Laval  <jeremie.laval@gmail.com>
+
+       * BlockingCollection.cs: New addition.
index 275ff55d53b8731148880042a60c6440d2136188..769a502b74d943595020be60008f728d67b16b7b 100644 (file)
@@ -1,3 +1,24 @@
+2009-08-17  Geoff Norton  <gnorton@novell.com>
+
+       * NtlmClient.cs: Mono.Http does not exist on monotouch
+
+2009-08-17  Sebastien Pouliot  <sebastien@ximian.com>
+
+       * CookieCollection.cs: Seal class for NET_2_1 (SL3)
+       * CookieContainer.cs: Seal class for NET_2_1 (SL3)
+       * NetworkCredential.cs: Use in NET_2_1 (SL3) but without implementing
+       ICredentialsByHost
+
+2009-08-13 Gonzalo Paniagua Javier <gonzalo@novell.com>
+
+       * HttpWebRequest.cs:
+       * WebConnectionStream.cs: if there's an error writing the headers from
+       a buffered request, propagate the error instead of hiding it and
+       causing a different one later (ie, ObjectDisposedException instead of
+       the original WebException). This happened when posting without
+       Content-Length set to an HTTPS url without validating the server
+       certificate.
+
 2009-07-28 Gonzalo Paniagua Javier <gonzalo@novell.com>
 
        * WebClient.cs: rethrow WebExceptions instead of creating a new one
index a7528bdf8df03facdcc4f908a0b07782ecea5f3b..b2ddafba9991237ed08cf8963dd6e2fa1a49eae4 100644 (file)
@@ -37,8 +37,11 @@ using System.Runtime.Serialization;
 namespace System.Net 
 {
        [Serializable]
-       public class CookieCollection : ICollection, IEnumerable
-       {
+#if NET_2_1
+       public sealed class CookieCollection : ICollection, IEnumerable {
+#else
+       public class CookieCollection : ICollection, IEnumerable {
+#endif
                class CookieCollectionPathComparer : IComparer
                {
                        int IComparer.Compare (object p1, object p2)
index ff122f90d674c7c8c7fc0586539835ff70dad170..d8a1222e407c992d24128e80acf12c3b3e900834 100644 (file)
@@ -40,8 +40,11 @@ namespace System.Net
 {
        [Serializable]
        [MonoTODO ("Need to remove older/unused cookies if it reaches the maximum capacity")]
-       public class CookieContainer
-       {
+#if NET_2_1
+       public sealed class CookieContainer {
+#else
+       public class CookieContainer {
+#endif
                public const int DefaultCookieLengthLimit = 4096;
                public const int DefaultCookieLimit = 300;
                public const int DefaultPerDomainCookieLimit = 20;
index 16feff0c86ae7bff4c8b93d854c4577887b53ff1..afe0adc2a88e6d58fac098c10c3137fb7a8d5fe7 100644 (file)
@@ -1068,11 +1068,6 @@ namespace System.Net
                        usedPreAuth = true;
                }
                
-               internal void SetWriteStreamError (WebExceptionStatus status)
-               {
-                       SetWriteStreamError (status, null);
-               }
-
                internal void SetWriteStreamError (WebExceptionStatus status, Exception exc)
                {
                        if (Aborted)
@@ -1097,7 +1092,7 @@ namespace System.Net
                        }
                }
 
-               internal void SendRequestHeaders ()
+               internal void SendRequestHeaders (bool propagate_error)
                {
                        StringBuilder req = new StringBuilder ();
                        string query;
@@ -1128,9 +1123,13 @@ namespace System.Net
                        try {
                                writeStream.SetHeaders (bytes);
                        } catch (WebException wexc) {
-                               SetWriteStreamError (wexc.Status);
-                       } catch (Exception) {
-                               SetWriteStreamError (WebExceptionStatus.SendFailure);
+                               SetWriteStreamError (wexc.Status, wexc);
+                               if (propagate_error)
+                                       throw;
+                       } catch (Exception exc) {
+                               SetWriteStreamError (WebExceptionStatus.SendFailure, exc);
+                               if (propagate_error)
+                                       throw;
                        }
                }
 
@@ -1146,7 +1145,7 @@ namespace System.Net
                                writeStream.SendChunked = false;
                        }
 
-                       SendRequestHeaders ();
+                       SendRequestHeaders (false);
 
                        haveRequest = true;
                        
index 5eea32028f2b8ecbbdd6eaf588d3214ad00470c3..2219e4b37dc2cdd585a7a60a328efd6bc942d3f9 100644 (file)
@@ -30,7 +30,7 @@
 namespace System.Net
 {
        public class NetworkCredential : ICredentials
-#if NET_2_0
+#if NET_2_0 && !NET_2_1
                                        , ICredentialsByHost
 #endif
        {
@@ -83,7 +83,7 @@ namespace System.Net
                        return this;
                }
 
-#if NET_2_0
+#if NET_2_0 && !NET_2_1
                public NetworkCredential GetCredential (string host, int port, string authenticationType)
                {
                        return this;
index 37257a3659ba275c65cbb45aedb9a02c13df3e28..7f0979716fc03ea576a276d725f734bf7c968416 100644 (file)
@@ -42,9 +42,11 @@ namespace System.Net
 
                static NtlmClient ()
                {
+#if !MONOTOUCH
                        Assembly ass = Assembly.Load (Consts.AssemblyMono_Http);
                        if (ass != null)
                                ntlmAuthType = ass.GetType ("Mono.Http.NtlmClient", false);
+#endif
                }
                
                public NtlmClient ()
index b8af255a530ec911af7ac7aa15581ac634115816..00fcd059681a7c46211d02bd20ea93838eb88f6e 100644 (file)
@@ -677,7 +677,7 @@ namespace System.Net
                                                        method == "TRACE" || method == "DELETE");
                                if (!no_writestream)
                                        request.InternalContentLength = length;
-                               request.SendRequestHeaders ();
+                               request.SendRequestHeaders (true);
                        }
                        WriteHeaders ();
                        if (cnc.Data.StatusCode != 0 && cnc.Data.StatusCode != 100)
index aea82d787f5b888c50a5d3451dad8716a5ee7d84..139e4bb5e7fedf669080c3f6b04311f171e35e8e 100644 (file)
@@ -1,3 +1,45 @@
+2009-08-18  Raja R Harinath  <harinath@hurrynot.org>
+
+       * parser.cs (GetMapping): Extend duplicate check for numeric
+       groups too.
+
+2009-08-17  Raja R Harinath  <harinath@hurrynot.org>
+
+       * parser.cs (ResolveReferences): Handle some cases of
+       explicitly-named numeric groups.
+
+2009-08-17  Raja R Harinath  <harinath@hurrynot.org>
+
+       * parser.cs (ResolveReferences): Rearrange slightly to prepare for
+       future changes.
+
+2009-08-17  Raja R Harinath  <harinath@hurrynot.org>
+
+       * Regex.cs (GetGroupNumbers): List group numbers in ascending order.
+       (GetGroupNames): List names in order of group number.
+
+2009-08-12  Raja R Harinath  <harinath@hurrynot.org>
+
+       * syntax.cs (BackslashNumber.ResolveReference): Improve ECMAScript
+       semantics.  Handle cases like "group 43 exists but group 4 doesn't".
+
+2009-08-10  Raja R Harinath  <harinath@hurrynot.org>
+
+       * syntax.cs (BackslashNumber.ResolveReference): Implement fallback
+       to octal numbers, and ECMAScript semantics.
+       * parser.cs (ResolveReferences): Use it.
+
+2009-08-10  Raja R Harinath  <harinath@hurrynot.org>
+
+       * syntax.cs (BackslashNumber): New class.
+       * parser.cs (ParseSpecial): Create it instead of 'Reference' if a
+       numeric backreference is seen.
+
+2009-08-10  Raja R Harinath  <harinath@hurrynot.org>
+
+       * parser.cs (ResolveReferences): Allow named groups to be
+       referred-to by their group numbers too.
+
 2009-04-23  Sebastien Pouliot  <sebastien@ximian.com>
 
        * Regex.cs: Remove Compiler-related support for NET_2_1
index d34fb777862473f592b1fe4d08882b075609cadf..96bdf740b6752f1caedb5426efd0730043a056c0 100644 (file)
@@ -299,17 +299,17 @@ namespace System.Text.RegularExpressions {
                
                public string [] GetGroupNames ()
                {
-                       string [] names = new string [mapping.Count];
-                       mapping.Keys.CopyTo (names, 0);
-
+                       string [] names = new string [1 + group_count];
+                       Array.Copy (_groupNumberToNameMap, names, 1 + group_count);
                        return names;
                }
 
                public int[] GetGroupNumbers ()
                {
-                       int[] numbers = new int [mapping.Count];
-                       mapping.Values.CopyTo (numbers, 0);
-
+                       int[] numbers = new int [1 + group_count];
+                       for (int i = 0; i <= group_count; ++i)
+                               numbers [i] = i;
+                       // FIXME: needs to handle arbitrarily numbered groups '(?<43>abc)'
                        return numbers;
                }
 
index f3ddf196730bb8879cbdc0dd8fc5a82829c91486..212e41adcaa5e9f606537a65435ab97537347cde 100644 (file)
@@ -156,16 +156,13 @@ namespace System.Text.RegularExpressions.Syntax {
                        mapping.Add ("0", 0);
                        for (int i = 0; i < end; i++) {
                                CapturingGroup group = (CapturingGroup) caps [i];
-                               if (group.Name != null) {
-                                       if (mapping.Contains (group.Name)) {
-                                               if ((int) mapping [group.Name] != group.Number)
-                                                       throw new SystemException ("invalid state");
-                                               continue;
-                                       }
-                                       mapping.Add (group.Name, group.Number);
-                               } else {
-                                       mapping.Add (group.Number.ToString (), group.Number);
+                               string name = group.Name != null ? group.Name : group.Number.ToString ();
+                               if (mapping.Contains (name)) {
+                                       if ((int) mapping [name] != group.Number)
+                                               throw new SystemException ("invalid state");
+                                       continue;
                                }
+                               mapping.Add (name, group.Number);
                        }
 
                        return mapping;
@@ -864,7 +861,7 @@ namespace System.Text.RegularExpressions.Syntax {
                                // FIXME test if number is within number of assigned groups
                                // this may present a problem for right-to-left matching
 
-                               Reference reference = new Reference (IsIgnoreCase (options));
+                               Reference reference = new BackslashNumber (IsIgnoreCase (options), ecma);
                                refs.Add (reference, n.ToString ());
                                expr = reference;
                                break;
@@ -1060,45 +1057,66 @@ namespace System.Text.RegularExpressions.Syntax {
                        return result.ToString ();
                }
 
-               private void ResolveReferences () {
+               private void ResolveReferences ()
+               {
                        int gid = 1;
                        Hashtable dict = new Hashtable ();
 
                        // number unnamed groups
 
                        foreach (CapturingGroup group in caps) {
-                               if (group.Name == null) {
-                                       dict.Add (gid.ToString (), group);
-                                       group.Number = gid ++;
+                               if (group.Name != null)
+                                       continue;
 
-                                       ++ num_groups;
-                               }
+                               dict.Add (gid.ToString (), group);
+                               group.Number = gid ++;
+                               ++ num_groups;
                        }
 
                        // number named groups
 
                        foreach (CapturingGroup group in caps) {
-                               if (group.Name != null) {
-                                       if (!dict.Contains (group.Name)) {
-                                               dict.Add (group.Name, group);
-                                               group.Number = gid ++;
+                               if (group.Name == null)
+                                       continue;
 
+                               if (dict.Contains (group.Name)) {
+                                       CapturingGroup prev = (CapturingGroup) dict [group.Name];
+                                       group.Number = prev.Number;
+                                       continue;
+                               }
+
+                               if (Char.IsDigit (group.Name [0])) {
+                                       int ptr = 0;
+                                       int group_gid = ParseDecimal (group.Name, ref ptr);
+                                       if (ptr == group.Name.Length) {
+                                               // FIXME: Handle non-contiguous groups
+                                               group.Number = group_gid;
+                                               dict.Add (group.Name, group);
                                                ++ num_groups;
-                                       }
-                                       else {
-                                               CapturingGroup prev = (CapturingGroup)dict[group.Name];
-                                               group.Number = prev.Number;
+                                               continue;
                                        }
                                }
+
+                               string gid_s = gid.ToString ();
+                               while (dict.Contains (gid_s))
+                                       gid_s = (++gid).ToString ();
+
+                               dict.Add (gid_s, group);
+                               dict.Add (group.Name, group);
+                               group.Number = gid ++;
+                               ++ num_groups;
                        }
 
                        // resolve references
 
                        foreach (Expression expr in refs.Keys) {
-                               string name = (string)refs[expr];
+                               string name = (string) refs [expr];
                                if (!dict.Contains (name)) {
                                        if (expr is CaptureAssertion && !Char.IsDigit (name [0]))
                                                continue;
+                                       BackslashNumber bn = expr as BackslashNumber;
+                                       if (bn != null && bn.ResolveReference (name, dict))
+                                               continue;
                                        throw NewParseException ("Reference to undefined group " +
                                                (Char.IsDigit (name[0]) ? "number " : "name ") +
                                                name);
index 9204010c2d849d2078c63abfdbca16ba9a32926a..265eb7eed8030c7c23f9c2de29126e063a664270 100644 (file)
@@ -702,7 +702,8 @@ namespace System.Text.RegularExpressions.Syntax {
                        set { ignore = value; }
                }
 
-               public override void Compile (ICompiler cmp, bool reverse) {
+               public static void CompileLiteral (string str, ICompiler cmp, bool ignore, bool reverse)
+               {
                        if (str.Length == 0)
                                return;
 
@@ -712,6 +713,11 @@ namespace System.Text.RegularExpressions.Syntax {
                                cmp.EmitString (str, ignore, reverse);
                }
 
+               public override void Compile (ICompiler cmp, bool reverse)
+               {
+                       CompileLiteral (str, cmp, ignore, reverse);
+               }
+
                public override void GetWidth (out int min, out int max) {
                        min = max = str.Length;
                }
@@ -797,6 +803,58 @@ namespace System.Text.RegularExpressions.Syntax {
                private bool ignore;
        }
 
+       class BackslashNumber : Reference {
+               string literal;
+               bool ecma;
+
+               public BackslashNumber (bool ignore, bool ecma)
+                       : base (ignore)
+               {
+                       this.ecma = ecma;
+               }
+
+               // Precondition: groups [num_str] == null
+               public bool ResolveReference (string num_str, Hashtable groups)
+               {
+                       if (ecma) {
+                               int last_i = 0;
+                               for (int i = 1; i < num_str.Length; ++i) {
+                                       if (groups [num_str.Substring (0, i)] != null)
+                                               last_i = i;
+                               }
+                               if (last_i != 0) {
+                                       CapturingGroup = (CapturingGroup) groups [num_str.Substring (0, last_i)];
+                                       literal = num_str.Substring (last_i);
+                                       return true;
+                               }
+                       } else {
+                               if (num_str.Length == 1)
+                                       return false;
+                       }
+
+                       int ptr = 0;
+                       int as_octal = Parser.ParseOctal (num_str, ref ptr);
+                       // Since ParseOctal reads at most 3 digits, as_octal <= octal 0777
+                       if (as_octal == -1)
+                               return false;
+                       if (as_octal > 0xff && ecma) {
+                               as_octal /= 8;
+                               --ptr;
+                       }
+                       as_octal &= 0xff;
+                       literal = ((char) as_octal) + num_str.Substring (ptr);
+                       return true;
+               }
+
+               public override void Compile (ICompiler cmp, bool reverse)
+               {
+                       if (CapturingGroup != null)
+                               base.Compile (cmp, reverse);
+                       if (literal != null)
+                               Literal.CompileLiteral (literal, cmp, IgnoreCase, reverse);
+               }
+       }
+
        class CharacterClass : Expression {
                public CharacterClass (bool negate, bool ignore) {
                        this.negate = negate;
diff --git a/mcs/class/System/System.Threading/Barrier.cs b/mcs/class/System/System.Threading/Barrier.cs
new file mode 100644 (file)
index 0000000..105783e
--- /dev/null
@@ -0,0 +1,166 @@
+#if NET_4_0
+// 
+// Barrier.cs
+//  
+// Author:
+//       Jérémie "Garuma" Laval <jeremie.laval@gmail.com>
+// 
+// Copyright (c) 2009 Jérémie "Garuma" Laval
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+// 
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using System;
+
+namespace System.Threading
+{
+       public class Barrier
+       {
+               readonly Action<Barrier> postPhaseAction;
+               
+               int participants;
+               CountdownEvent cntd;
+               AtomicBoolean cleaned = new AtomicBoolean ();
+               int phase;
+               
+               public Barrier (int participants) : this (participants, null)
+               {
+               }
+               
+               public Barrier (int participants, Action<Barrier> postPhaseAction)
+               {
+                       this.participants = participants;
+                       this.postPhaseAction = postPhaseAction;
+                       
+                       InitCountdownEvent ();
+               }
+               
+               void InitCountdownEvent ()
+               {
+                       cleaned = new AtomicBoolean ();
+                       cntd = new CountdownEvent (participants);
+               }
+               
+               public int AddParticipant ()
+               {
+                       return AddParticipants (1);
+               }
+               
+               public int AddParticipants (int participantCount)
+               {
+                       // Basically, we try to add ourselves and return
+                       // the phase. If the call return false, we repeatdly try
+                       // to add ourselves for the next phase
+                       do {
+                               if (cntd.TryAddCount (participantCount)) {
+                                       Interlocked.Add (ref participants, participantCount);
+                                       return phase;
+                               }
+                       } while (true);
+               }
+               
+               public void RemoveParticipant ()
+               {
+                       RemoveParticipants (1);
+               }
+               
+               public void RemoveParticipants (int participantCount)
+               {
+                       cntd.Signal (participantCount);
+                       Interlocked.Add (ref participants, -participantCount);
+               }
+               
+               public void SignalAndWait ()
+               {
+                       SignalAndWait ((c) => { c.Wait (); return true; });
+               }
+               
+               public bool SignalAndWait (int millisecondTimeout)
+               {
+                       return SignalAndWait ((c) => c.Wait (millisecondTimeout));
+               }
+               
+               public bool SignalAndWait (TimeSpan ts)
+               {
+                       return SignalAndWait ((c) => c.Wait (ts));
+               }
+               
+               public bool SignalAndWait (int millisecondTimeout, CancellationToken token)
+               {
+                       return SignalAndWait ((c) => c.Wait (millisecondTimeout, token));
+               }
+               
+               public bool SignalAndWait (TimeSpan ts, CancellationToken token)
+               {
+                       return SignalAndWait ((c) => c.Wait (ts, token));
+               }
+               
+               bool SignalAndWait (Func<CountdownEvent, bool> associate)
+               {
+                       bool result;
+                       AtomicBoolean cl = cleaned;
+                       CountdownEvent temp = cntd;
+                       
+                       if (!temp.Signal ()) {
+                               result = Wait (associate, temp, cl);
+                       } else {
+                               result = true;
+                               PostPhaseAction (cl);
+                               phase++;
+                       }
+                       
+                       return result;
+               }
+               
+               bool Wait (Func<CountdownEvent, bool> associate, CountdownEvent temp, AtomicBoolean cl)
+               {
+                       if (!associate (temp))
+                               return false;
+                       
+                       SpinWait sw = new SpinWait ();
+                       while (!cl.Value) {
+                               //Console.WriteLine (cleaned);
+                               sw.SpinOnce ();
+                       }
+                       
+                       return true;
+               }
+               
+               void PostPhaseAction (AtomicBoolean cl)
+               {
+                       postPhaseAction (this);
+                       
+                       InitCountdownEvent ();
+                       
+                       cl.Value = true;
+               }
+               
+               public int CurrentPhaseNumber {
+                       get {
+                               return phase;
+                       }
+               }
+               
+               public int ParticipantCount  {
+                       get {
+                               return participants;
+                       }
+               }
+       }
+}
+#endif
index 8fa1fe4e8b6e2326a28461deabf4cc470c3cb2aa..8e816821de198fcaa422ea409c2cd85d98575009 100644 (file)
@@ -1,3 +1,12 @@
+2009-08-19  Jérémie Laval  <jeremie.laval@gmail.com>
+
+       * Barrier.cs: Fix Barrier to be really thread-safe.
+       Remove deadlocking.
+
+2009-08-11  Jérémie Laval  <jeremie.laval@gmail.com>
+
+       * Barrier.cs: added.
+
 2006-09-28  Andrew Skiba <andrews@mainsoft.com>
 
        * Semaphore.cs: TARGET_JVM
index c50236eae37222f2ca555f6182bf91475d5de19f..a67d8b4944c962f4092a6f97905e59ed6ce56324 100644 (file)
@@ -951,6 +951,7 @@ System.Threading/Semaphore.cs
 System.Threading/SemaphoreFullException.cs
 System.Threading/ThreadExceptionEventArgs.cs
 System.Threading/ThreadExceptionEventHandler.cs
+System.Threading/Barrier.cs
 System.Timers/ElapsedEventArgs.cs
 System.Timers/ElapsedEventHandler.cs
 System.Timers/Timer.cs
@@ -1007,3 +1008,5 @@ System.Runtime.InteropServices.ComTypes/STGMEDIUM.cs
 System.Runtime.InteropServices.ComTypes/TYMED.cs
 System/IUriData.cs
 System/UriData.cs
+System.Collections.Concurrent/BlockingCollection.cs
+../corlib/System.Threading/AtomicBoolean.cs
index eae59da5b01a56376db9f8073401d85b3d2fb1d2..94c36b0f4d94e76630b604ef4b273678104f4fe9 100644 (file)
@@ -471,3 +471,4 @@ System.Timers/ElapsedEventArgsCas.cs
 System.Timers/TimerCas.cs
 System.Web/AspNetHostingPermissionCas.cs
 System.Web/AspNetHostingPermissionAttributeCas.cs
+System.Collections.Concurrent/BlockingCollectionTests.cs
index 85bc55245308ecb54bb2a968f36757e100dfcb3f..a5db9f45562eabaf220ab47fb248e006118cc8d2 100644 (file)
@@ -1,3 +1,7 @@
+2009-08-13  Marek Habersack  <mhabersack@novell.com>
+
+       * CodeTypeReferenceTest.cs: added test for bug #523341
+
 2007-01-25  Ilya Kharmatsky  <ilyak -at- mainsoft.com>
        
        * CodeTypeReferenceTest.cs :
index fb38cfbf2711558da26c4708fee7bffa1f1f4809..aee90f00748d58021ca9e515b021111bade002ee 100644 (file)
@@ -586,6 +586,18 @@ namespace MonoTests.System.CodeDom
                        Assert.IsNotNull (reference.TypeArguments, "#5");
                        Assert.AreEqual (0, reference.TypeArguments.Count, "#6");
                }
+
+               [Test (Description="Bug #523341")]
+               public void GenericTypeTest6 ()
+               {
+                       CodeTypeReference reference = new CodeTypeReference ("System.Collections.List<System.Globalization.CultureInfo[]>");
+                       Assert.AreEqual ("System.Collections.List<System.Globalization.CultureInfo[]>", reference.BaseType, "#1");
+                       Assert.AreEqual (0, reference.ArrayRank, "#2");
+                       Assert.IsNull (reference.ArrayElementType, "#3");
+                       Assert.AreEqual (0, (int) reference.Options, "#4");
+                       Assert.IsNotNull (reference.TypeArguments, "#5");
+                       Assert.AreEqual (0, reference.TypeArguments.Count, "#6");
+               }
 #endif
 
                // bug #76535
diff --git a/mcs/class/System/Test/System.Collections.Concurrent/BlockingCollectionTests.cs b/mcs/class/System/Test/System.Collections.Concurrent/BlockingCollectionTests.cs
new file mode 100644 (file)
index 0000000..cfc9425
--- /dev/null
@@ -0,0 +1,164 @@
+#if NET_4_0
+// BlockingCollectionTests.cs
+//
+// Copyright (c) 2008 Jérémie "Garuma" Laval
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+//
+
+using System;
+using System.Threading;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+
+using NUnit.Framework;
+
+namespace ParallelFxTests
+{
+       [TestFixture()]
+       public class BlockingCollectionTests
+       {
+               BlockingCollection<int> defaultCollection;
+               BlockingCollection<int> boundedCollection;
+               
+               [SetUpAttribute]
+               public void Setup()
+               {
+                       defaultCollection = new BlockingCollection<int>();
+                       boundedCollection = new BlockingCollection<int>(10);
+               }
+               
+               [TestAttribute]
+               public void DefaultAddTestCase()
+               {
+                       defaultCollection.Add(1);
+                       defaultCollection.Add(2);
+                       Assert.AreEqual(2, defaultCollection.Count, "#1");
+
+               }
+               
+               [TestAttribute]
+               public void BoundedAddTestCase()
+               {
+                       boundedCollection.Add(1);
+                       boundedCollection.Add(2);
+                       Assert.AreEqual(2, boundedCollection.Count, "#1");
+               }
+               
+               [TestAttribute]
+               public void BoundedIsFullTestCase()
+               {
+                       boundedCollection.Add(1);
+                       boundedCollection.Add(2);
+                       boundedCollection.Add(3);
+                       boundedCollection.Add(4);
+                       boundedCollection.Add(5);
+                       boundedCollection.Add(6);
+                       boundedCollection.Add(7);
+                       boundedCollection.Add(8);
+                       boundedCollection.Add(9);
+                       boundedCollection.Add(10);
+                       Assert.AreEqual(boundedCollection.BoundedCapacity, boundedCollection.Count, "#1");
+               }
+               
+               [TestAttribute]
+               public void TakeTestCase()
+               {
+                       defaultCollection.Add(1);
+                       defaultCollection.Add(2);
+                       boundedCollection.Add(1);
+                       boundedCollection.Add(2);
+                       
+                       int value = defaultCollection.Take();
+                       Assert.AreEqual(1, value, "#1");
+                       value = boundedCollection.Take();
+                       Assert.AreEqual(1, value, "#2");
+               }
+               
+               [TestAttribute, ExpectedExceptionAttribute(typeof(InvalidOperationException))]
+               public void DefaultAddCompletedTestCase()
+               {
+                       defaultCollection.Add(1);
+                       defaultCollection.Add(2);
+                       defaultCollection.CompleteAdding();
+                       Assert.IsTrue(defaultCollection.IsAddingCompleted, "#1");
+                       
+                       defaultCollection.Add(3);
+               }
+               
+               [TestAttribute, ExpectedExceptionAttribute(typeof(InvalidOperationException))]
+               public void BoundedAddCompletedTestCase()
+               {
+                       boundedCollection.Add(1);
+                       boundedCollection.Add(2);
+                       boundedCollection.Add(3);
+                       boundedCollection.Add(4);
+                       boundedCollection.Add(5);
+                       boundedCollection.Add(6);
+                       boundedCollection.Add(7);
+                       boundedCollection.Add(8);
+                       boundedCollection.Add(9);
+                       boundedCollection.Add(10);
+                       boundedCollection.CompleteAdding();
+                       Assert.IsTrue(boundedCollection.IsAddingCompleted, "#1");
+                       
+                       boundedCollection.Add(3);
+               }
+               
+               [TestAttribute]
+               public void IsCompletedTestCase()
+               {
+                       defaultCollection.Add(1);
+                       defaultCollection.Add(2);
+                       
+                       defaultCollection.CompleteAdding();
+                       Assert.IsFalse(defaultCollection.IsCompleted, "#3");
+                       
+                       defaultCollection.Take();
+                       defaultCollection.Take();
+                       
+                       Assert.IsTrue(defaultCollection.IsAddingCompleted, "#1");
+                       Assert.AreEqual(0, defaultCollection.Count, "#2");
+                       Assert.IsTrue(defaultCollection.IsCompleted, "#4");
+               }
+               
+               [TestAttribute]
+               public void ConsumingEnumerableTestCase()
+               {
+                       defaultCollection.Add(1);
+                       defaultCollection.Add(2);
+                       defaultCollection.Add(3);
+                       defaultCollection.Add(4);
+                       defaultCollection.Add(5);
+                       defaultCollection.Add(6);
+                       defaultCollection.CompleteAdding ();
+                       
+                       IEnumerable<int> enumerable = defaultCollection.GetConsumingEnumerable();
+                       Assert.IsNotNull(enumerable, "#1");
+                       int i = 1;
+                       foreach (int j in enumerable) {
+                               int temp = i++;
+                               Assert.AreEqual(temp, j, "#" + temp);
+                       }
+                       Assert.AreEqual(0, defaultCollection.Count, "#" + i);
+               }
+       }
+}
+#endif
diff --git a/mcs/class/System/Test/System.Collections.Concurrent/ChangeLog b/mcs/class/System/Test/System.Collections.Concurrent/ChangeLog
new file mode 100644 (file)
index 0000000..8138790
--- /dev/null
@@ -0,0 +1,4 @@
+2009-08-19 Jérémie Laval  <jeremie.laval@gmail.com>
+
+       * BlockingCollectionTests.cs: track API changes
+
index 7ae8f624c8508d5db7870646ebe0f26bd1997d97..fa2e8ec119bb0dff6b304bd26be1f5f35c85aa0c 100644 (file)
@@ -1,3 +1,19 @@
+2009-08-17  Raja R Harinath  <harinath@hurrynot.org>
+
+       * RegexMatchTests.cs (RegexTrial0061): New.
+
+2009-08-17  Raja R Harinath  <harinath@hurrynot.org>
+
+       * RegexTrial.cs (Execute): Prepare to handle dis-contiguous group numbers.
+
+2009-08-10  Raja R Harinath  <harinath@hurrynot.org>
+
+       * RegexMatchTests.cs (RegexTrial0054..60): New.
+
+2009-08-10  Raja R Harinath  <harinath@hurrynot.org>
+
+       * RegexMatchTests.cs (RegexTrial0053): New.
+
 2009-02-27  Jonathan Pryor <jpryor@novell.com>
 
        * RegexReplace.cs: Add null argument checks for Regex.Replace().
index fa60eb67e3aaa180345a932604d41430e18793c6..a2b4feac50af0f4e9d55d0fc86595f5f40018512 100644 (file)
@@ -148,6 +148,17 @@ namespace MonoTests.System.Text.RegularExpressions
                        new RegexTrial (@"abc*(?!c{1,})", RegexOptions.None, "abcc", "Pass. Group[0]=(0,4)"),//50
                        new RegexTrial (@"(a)(?<1>b)(?'1'c)", RegexOptions.ExplicitCapture, "abc", "Pass. Group[0]=(0,3) Group[1]=(1,1)(2,1)"),//51
                        new RegexTrial (@"(?>a*).", RegexOptions.ExplicitCapture, "aaaa", "Fail."),//52
+
+                       new RegexTrial (@"(?<ab>ab)c\1", RegexOptions.None, "abcabc", "Pass. Group[0]=(0,5) Group[1]=(0,2)"),//53
+                       new RegexTrial (@"\1", RegexOptions.ECMAScript, "-", "Fail."),//54
+                       new RegexTrial (@"\2", RegexOptions.ECMAScript, "-", "Fail."),//55
+                       new RegexTrial (@"(a)|\2", RegexOptions.ECMAScript, "-", "Fail."),//56
+                       new RegexTrial (@"\4400", RegexOptions.None, "asdf 012", "Pass. Group[0]=(4,2)"),//57
+                       new RegexTrial (@"\4400", RegexOptions.ECMAScript, "asdf 012", "Fail."),//58
+                       new RegexTrial (@"\4400", RegexOptions.None, "asdf$0012", "Fail."),//59
+                       new RegexTrial (@"\4400", RegexOptions.ECMAScript, "asdf$0012", "Pass. Group[0]=(4,3)"),//60
+                       new RegexTrial (@"(?<2>ab)(?<c>c)(?<d>d)", RegexOptions.None, "abcd", "Pass. Group[0]=(0,4) Group[1]=(2,1) Group[2]=(0,2) Group[3]=(3,1)"),// 61
+                       new RegexTrial (@"(?<1>ab)(c)", RegexOptions.None, "abc", "Pass. Group[0]=(0,3) Group[1]=(0,2)(2,1)"),//62
                };
 
                [Test]
@@ -318,5 +329,16 @@ namespace MonoTests.System.Text.RegularExpressions
                [Test]  public void RegexJvmTrial0050 () { trials [50].Execute (); }
                [Test]  public void RegexJvmTrial0051 () { trials [51].Execute (); }
                [Test]  public void RegexJvmTrial0052 () { trials [52].Execute (); }
+
+               [Test]  public void RegexTrial0053 () { trials [53].Execute (); }
+               [Test]  public void RegexTrial0054 () { trials [54].Execute (); }
+               [Test]  public void RegexTrial0055 () { trials [55].Execute (); }
+               [Test]  public void RegexTrial0056 () { trials [56].Execute (); }
+               [Test]  public void RegexTrial0057 () { trials [57].Execute (); }
+               [Test]  public void RegexTrial0058 () { trials [58].Execute (); }
+               [Test]  public void RegexTrial0059 () { trials [59].Execute (); }
+               [Test]  public void RegexTrial0060 () { trials [60].Execute (); }
+               [Test]  public void RegexTrial0061 () { trials [61].Execute (); }
+               [Test]  public void RegexTrial0062 () { trials [62].Execute (); }
        }
 }
index 0c2d0818f41092430772828d2ad06b8e63e60243..ab4fecc0d04997cae65b45fe27d20547c01877e4 100644 (file)
@@ -37,15 +37,17 @@ namespace MonoTests.System.Text.RegularExpressions {
                                RegexOptions real_options = (compiled == 1) ? (options | RegexOptions.Compiled) : options;
                                try {
                                        Regex re = new Regex (pattern, real_options);
+                                       int [] group_nums = re.GetGroupNumbers ();
                                        Match m = re.Match (input);
 
                                        if (m.Success) {
                                                result = "Pass.";
-                                       
+
                                                for (int i = 0; i < m.Groups.Count; ++ i) {
-                                                       Group group = m.Groups [i];
+                                                       int gid = group_nums [i];
+                                                       Group group = m.Groups [gid];
 
-                                                       result += " Group[" + i + "]=";
+                                                       result += " Group[" + gid + "]=";
                                                        foreach (Capture cap in group.Captures)
                                                                result += "(" + cap.Index + "," + cap.Length + ")";
                                                }
index 5200a2bde0b07cbfe3578be7842355f574f99583..f7b593e25a77c9f544ce44d318980782b64098c6 100644 (file)
@@ -1,3 +1,8 @@
+2009-08-11  Jérémie Laval  <jeremie.laval@gmail.com>
+
+       * corlib.dll.sources: Update with moved files.
+       * corlib_test.dll.source: Updated with moved files.
+
 2009-07-31  Jérémie Laval  <jeremie.laval@gmail.com>
 
         * corlib.dll.sources: Added TaskCompletionSource
diff --git a/mcs/class/corlib/System.Collections.Concurrent/BlockingCollection.cs b/mcs/class/corlib/System.Collections.Concurrent/BlockingCollection.cs
deleted file mode 100644 (file)
index 0884738..0000000
+++ /dev/null
@@ -1,385 +0,0 @@
-#if NET_4_0
-// BlockingCollection.cs
-//
-// Copyright (c) 2008 Jérémie "Garuma" Laval
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-//
-
-using System;
-using System.Threading;
-using System.Collections;
-using System.Collections.Generic;
-
-namespace System.Collections.Concurrent
-{
-       public class BlockingCollection<T> : IEnumerable<T>, ICollection, IEnumerable, IDisposable
-       {
-               readonly IProducerConsumerCollection<T> underlyingColl;
-               readonly int upperBound;
-               readonly Func<bool> isFull;
-               
-               readonly SpinWait sw = new SpinWait ();
-               
-               AtomicBoolean isComplete;
-               
-               #region ctors
-               public BlockingCollection ()
-                       : this (new ConcurrentQueue<T> (), -1)
-               {
-               }
-               
-               public BlockingCollection (int upperBound)
-                       : this (new ConcurrentQueue<T> (), upperBound)
-               {
-               }
-               
-               public BlockingCollection (IProducerConsumerCollection<T> underlyingColl)
-                       : this (underlyingColl, -1)
-               {
-               }
-               
-               public BlockingCollection (IProducerConsumerCollection<T> underlyingColl, int upperBound)
-               {
-                       this.underlyingColl = underlyingColl;
-                       this.upperBound     = upperBound;
-                       this.isComplete     = new AtomicBoolean ();
-                       
-                       if (upperBound == -1)
-                               isFull = FalseIsFull;
-                       else
-                               isFull = CountBasedIsFull;
-               }
-               
-               static bool FalseIsFull ()
-               {
-                       return false;
-               }
-               
-               bool CountBasedIsFull ()
-               {
-                       return underlyingColl.Count >= upperBound;      
-               }
-               #endregion
-               
-               #region Add & Remove (+ Try)
-               public void Add (T item)
-               {
-                       while (true) {
-                               while (isFull ()) {
-                                       if (isComplete.Value)
-                                               throw new InvalidOperationException ("The BlockingCollection<T>"
-                                                                                    + " has been marked as complete with regards to additions.");
-                                       Block ();
-                               }
-                               // Extra check. The status might have changed after Block() or if isFull() is always false
-                               if (isComplete.Value)
-                                       throw new InvalidOperationException ("The BlockingCollection<T> has"
-                                                                            + " been marked as complete with regards to additions.");
-                               // Go back in main waiting loop
-                               if (isFull ())
-                                       continue;
-                               
-                               if (underlyingColl.TryAdd (item))
-                                       break;
-                       }
-               }
-               
-               public T Remove ()
-               {
-                       T item;
-                       
-                       while (underlyingColl.Count == 0 || !underlyingColl.TryTake (out item)) {
-                               if (isComplete.Value)
-                                       throw new OperationCanceledException ("The BlockingCollection<T> is empty and has been marked as complete with regards to additions.");
-                               Block ();
-                       }
-                       
-                       return item;
-               }
-               
-               public bool TryAdd (T item)
-               {
-                       if (isComplete.Value || isFull ()) {
-                                       return false;
-                       }
-                       
-                       return underlyingColl.TryAdd (item);
-               }
-               
-               public bool TryAdd (T item, TimeSpan ts)
-               {
-                       return TryAdd (item, (int)ts.TotalMilliseconds);
-               }
-               
-               public bool TryAdd (T item, int millisecondsTimeout)
-               {
-                       Watch sw = Watch.StartNew ();
-                       while (isFull ()) {
-                               if (isComplete.Value || sw.ElapsedMilliseconds > millisecondsTimeout) {
-                                       sw.Stop ();
-                                       return false;
-                               }
-                               Block ();
-                       }
-                       return TryAdd (item);
-               }
-               
-               public bool TryRemove (out T item)
-               {
-                       return underlyingColl.TryTake (out item);
-               }
-               
-               public bool TryRemove (out T item, TimeSpan ts)
-               {
-                       return TryRemove (out item, (int)ts.TotalMilliseconds);
-               }
-               
-               public bool TryRemove (out T item, int millisecondsTimeout)
-               {
-                       Watch sw = Watch.StartNew ();
-                       while (underlyingColl.Count == 0) {
-                               if (isComplete.Value || sw.ElapsedMilliseconds > millisecondsTimeout) {
-                                       item = default (T);
-                                       return false;
-                               }
-                                       
-                               Block ();
-                       }
-                       return TryRemove (out item);
-               }
-               #endregion
-               
-               #region static methods
-               static void CheckArray (BlockingCollection<T>[] collections)
-               {
-                       if (collections == null)
-                               throw new ArgumentNullException ("collections");
-                       if (collections.Length == 0 || IsThereANullElement (collections))
-                               throw new ArgumentException ("The collections argument is a 0-length array or contains a null element.", "collections");
-               }
-               
-               static bool IsThereANullElement (BlockingCollection<T>[] collections)
-               {
-                       foreach (BlockingCollection<T> e in collections)
-                               if (e == null)
-                                       return true;
-                       return false;
-               }
-               
-               public static int AddAny (BlockingCollection<T>[] collections, T item)
-               {
-                       CheckArray (collections);
-                       int index = 0;
-                       foreach (var coll in collections) {
-                               try {
-                                       coll.Add (item);
-                                       return index;
-                               } catch {}
-                               index++;
-                       }
-                       return -1;
-               }
-               
-               public static int TryAddAny (BlockingCollection<T>[] collections, T item)
-               {
-                       CheckArray (collections);
-                       int index = 0;
-                       foreach (var coll in collections) {
-                               if (coll.TryAdd (item))
-                                       return index;
-                               index++;
-                       }
-                       return -1;
-               }
-               
-               public static int TryAddAny (BlockingCollection<T>[] collections, T item, TimeSpan ts)
-               {
-                       CheckArray (collections);
-                       int index = 0;
-                       foreach (var coll in collections) {
-                               if (coll.TryAdd (item, ts))
-                                       return index;
-                               index++;
-                       }
-                       return -1;
-               }
-               
-               public static int TryAddAny (BlockingCollection<T>[] collections, T item, int millisecondsTimeout)
-               {
-                       CheckArray (collections);
-                       int index = 0;
-                       foreach (var coll in collections) {
-                               if (coll.TryAdd (item, millisecondsTimeout))
-                                       return index;
-                               index++;
-                       }
-                       return -1;
-               }
-               
-               public static int RemoveAny (BlockingCollection<T>[] collections, out T item)
-               {
-                       item = default (T);
-                       CheckArray (collections);
-                       int index = 0;
-                       foreach (var coll in collections) {
-                               try {
-                                       item = coll.Remove ();
-                                       return index;
-                               } catch {}
-                               index++;
-                       }
-                       return -1;
-               }
-               
-               public static int TryRemoveAny (BlockingCollection<T>[] collections, out T item)
-               {
-                       item = default (T);
-                       
-                       CheckArray (collections);
-                       int index = 0;
-                       foreach (var coll in collections) {
-                               if (coll.TryRemove (out item))
-                                       return index;
-                               index++;
-                       }
-                       return -1;
-               }
-               
-               public static int TryRemoveAny (BlockingCollection<T>[] collections, out T item, TimeSpan ts)
-               {
-                       item = default (T);
-                       
-                       CheckArray (collections);
-                       int index = 0;
-                       foreach (var coll in collections) {
-                               if (coll.TryRemove (out item, ts))
-                                       return index;
-                               index++;
-                       }
-                       return -1;
-               }
-               
-               public static int TryRemoveAny (BlockingCollection<T>[] collections, out T item, int millisecondsTimeout)
-               {
-                       item = default (T);
-                       
-                       CheckArray (collections);
-                       int index = 0;
-                       foreach (var coll in collections) {
-                               if (coll.TryRemove (out item, millisecondsTimeout))
-                                       return index;
-                               index++;
-                       }
-                       return -1;
-               }
-               #endregion
-               
-               public void CompleteAdding ()
-               {
-                       isComplete.Value = true;
-               }
-               
-               void ICollection.CopyTo (Array array, int index)
-               {
-                       underlyingColl.CopyTo (array, index);
-               }
-               
-               public void CopyTo (T[] array, int index)
-               {
-                       underlyingColl.CopyTo (array, index);
-               }
-               
-               public IEnumerable<T> GetConsumingEnumerable ()
-               {
-                       T item;
-                       while (underlyingColl.TryTake (out item)) {
-                               yield return item;
-                       }
-               }
-               
-               IEnumerator IEnumerable.GetEnumerator ()
-               {
-                       return ((IEnumerable)underlyingColl).GetEnumerator ();
-               }
-               
-               IEnumerator<T> IEnumerable<T>.GetEnumerator ()
-               {
-                       return ((IEnumerable<T>)underlyingColl).GetEnumerator ();
-               }
-               
-               public IEnumerator<T> GetEnumerator ()
-               {
-                       return ((IEnumerable<T>)underlyingColl).GetEnumerator ();
-               }
-               
-               public void Dispose ()
-               {
-               }
-               
-               public T[] ToArray ()
-               {
-                       return underlyingColl.ToArray ();
-               }
-               
-               // Method used to stall the thread for a limited period of time before retrying an operation
-               void Block ()
-               {
-                       sw.SpinOnce ();
-               }
-               
-               public int BoundedCapacity {
-                       get {
-                               return upperBound;
-                       }
-               }
-               
-               public int Count {
-                       get {
-                               return underlyingColl.Count;
-                       }
-               }
-               
-               public bool IsAddingCompleted {
-                       get {
-                               return isComplete.Value;
-                       }
-               }
-               
-               public bool IsCompleted {
-                       get {
-                               return isComplete.Value && underlyingColl.Count == 0;
-                       }
-               }
-               
-               object ICollection.SyncRoot {
-                       get {
-                               return underlyingColl.SyncRoot;
-                       }
-               }
-               
-               bool ICollection.IsSynchronized {
-                       get {
-                               return underlyingColl.IsSynchronized;
-                       }
-               }
-       }
-}
-#endif
index 44c6ec92c9b06912c8eb861889ed09d32226d93c..a1f5d2223c124de87cb6548861e7fe97f23c379f 100644 (file)
@@ -1,3 +1,20 @@
+2009-08-19  Jérémie Laval  <jeremie.laval@gmail.com>
+
+       * Partitioner.cs: Fix infinite recursion when calling Create
+       with a IList.
+       * Partitionners/ListPartitioner.cs: Fix bad splitting for the
+       last partition.
+
+2009-08-11  Jérémie Laval  <jeremie.laval@gmail.com>
+
+       * ConcurrentQueue.cs:
+       * IProducerConsumerCollection.cs: Add BOOTSTRAP_NET_4_0.
+
+2009-08-11  Jérémie Laval  <jeremie.laval@gmail.com>
+
+       * BlockingCollection.cs: Moved type.
+
+
 2009-08-04 Jérémie Laval  <jeremie.laval@gmail.com>
 
        * ConcurrentDictionary: Fix compilation issue
index 39163e94e0b04e9d2bc810121013487db0d64643..e55b123a5bd593028928f7620aeed54180e07cd6 100644 (file)
@@ -1,4 +1,4 @@
-#if NET_4_0
+#if NET_4_0 || BOOTSTRAP_NET_4_0
 // ConcurrentQueue.cs
 //
 // Copyright (c) 2008 Jérémie "Garuma" Laval
index ddb6133b4e7e90fc8c173217d60c85209cd60dc5..b9f10598bdbb7130f6f6165a444690a7d757aa41 100644 (file)
@@ -1,4 +1,4 @@
-#if NET_4_0
+#if NET_4_0 || BOOTSTRAP_NET_4_0
 // IConcurrentCollection.cs
 //
 // Copyright (c) 2008 Jérémie "Garuma" Laval
index c82398ac0799e30d6b2bbcb53838f1263dbee95e..b6655578d2d1fc865f8edcecafb200951a1b5121 100644 (file)
@@ -36,14 +36,14 @@ namespace System.Collections.Concurrent
                {
                        IList<TSource> tempIList = source as IList<TSource>;
                        if (tempIList != null)
-                               return Create (tempIList);
+                               return Create (tempIList, true);
                        
                        return new EnumerablePartitioner<TSource> (source);
                }
                
          public static OrderablePartitioner<TSource> Create<TSource> (TSource[] source, bool loadBalance)
                {
-                       return Create ((IList<TSource>)source);
+                       return Create ((IList<TSource>)source, loadBalance);
                }
                
          public static OrderablePartitioner<TSource> Create<TSource> (IList<TSource> source, bool loadBalance)
index 527df2d23d9c176c7dcff479d419f39eaacf61bf..37b0fdddfc2ae98e2ce96f4cbee572974b2b1a9d 100644 (file)
@@ -53,18 +53,18 @@ namespace System.Collections.Concurrent
                                if (i != enumerators.Length - 1)
                                        enumerators[i] = GetEnumeratorForRange (i * count, i * count + count);
                                else
-                                       enumerators[i] = GetEnumeratorForRange (i * count, source.Count - i * count);
+                                       enumerators[i] = GetEnumeratorForRange (i * count, source.Count);
                        }
                        
                        return enumerators;
                }
                
-               IEnumerator<KeyValuePair<long, T>> GetEnumeratorForRange (int startIndex, int count)
+               IEnumerator<KeyValuePair<long, T>> GetEnumeratorForRange (int startIndex, int lastIndex)
                {
                        if (startIndex >= source.Count)
                          return GetEmpty ();
                        
-                       return GetEnumeratorForRangeInternal (startIndex, count);
+                       return GetEnumeratorForRangeInternal (startIndex, lastIndex);
                }
 
                IEnumerator<KeyValuePair<long, T>> GetEmpty ()
@@ -72,9 +72,9 @@ namespace System.Collections.Concurrent
                        yield break;
                  }
                
-               IEnumerator<KeyValuePair<long, T>> GetEnumeratorForRangeInternal (int startIndex, int count)
+               IEnumerator<KeyValuePair<long, T>> GetEnumeratorForRangeInternal (int startIndex, int lastIndex)
                {       
-                       for (int i = startIndex; i < count; i++) {
+                       for (int i = startIndex; i < lastIndex; i++) {
                                yield return new KeyValuePair<long, T> (i, source[i]);
                        }
                }
index 980ecd3dc96b0b136785bb6d2607d611b7755368..6cb8ddabaa04008586dd091029e38227ac1309d6 100644 (file)
@@ -1,3 +1,16 @@
+2009-08-18  Zoltan Varga  <vargaz@gmail.com>
+
+       * MonoGenericClass.cs: Use StringComparison.Ordinal when calling
+       String.EndsWith ().
+
+2009-08-07 Rodrigo Kumpera  <rkumpera@novell.com>
+
+       * MonoGenericClass.cs: Implement almost all methods required
+       to move to inherit from System.Type. The only missing methods
+       are Is(Array|Pointer|ByRef)Impl and GetElementType since the
+       runtime still generates weird instances for generics instances
+       of non-SRE types with SRE types as generic arguments.
+
 2009-08-06 Rodrigo Kumpera  <rkumpera@novell.com>
 
        * MonoGenericClass.cs (InflateType): Add support to inflate
index 4eb43c9fff52e96eedea30c1329d1b15f5a7f44a..51b5ac27920a2806d72112e924a4ac37663dea21 100644 (file)
@@ -131,7 +131,11 @@ namespace System.Reflection
                        if (type.IsArray) {
                                if (type.GetArrayRank () > 1)
                                        return InflateType (type.GetElementType (), method_args).MakeArrayType (type.GetArrayRank ());
-                               if (type.ToString ().EndsWith ("[*]")) /*FIXME, the reflection API doesn't offer a way around this*/
+#if BOOTSTRAP_NET_2_0
+                               if (type.ToString ().EndsWith ("[*]"))
+#else
+                               if (type.ToString ().EndsWith ("[*]", StringComparison.Ordinal)) /*FIXME, the reflection API doesn't offer a way around this*/
+#endif
                                        return InflateType (type.GetElementType (), method_args).MakeArrayType (1);
                                return InflateType (type.GetElementType (), method_args).MakeArrayType ();
                        }
@@ -710,6 +714,11 @@ namespace System.Reflection
                        return new PointerType (this);
                }
 
+               /*public override Type GetElementType ()
+               {
+                       throw new NotSupportedException ();
+               }*/
+
                protected override bool IsCOMObjectImpl ()
                {
                        return false;
@@ -719,6 +728,105 @@ namespace System.Reflection
                {
                        return false;
                }
+
+               /*
+               protected override bool IsArrayImpl ()
+               {
+                       return false;
+               }
+
+               protected override bool IsByRefImpl ()
+               {
+                       return false;
+               }
+
+               protected override bool IsPointerImpl ()
+               {
+                       return false;
+               }*/
+
+               protected override TypeAttributes GetAttributeFlagsImpl ()
+               {
+                       return generic_type.Attributes; 
+               }
+
+               //stuff that throws
+               public override Type GetInterface (string name, bool ignoreCase)
+               {
+                       throw new NotSupportedException ();
+               }
+
+               public override EventInfo GetEvent (string name, BindingFlags bindingAttr)
+               {
+                       if (!generic_type.IsCompilerContext)
+                               throw new NotSupportedException ();
+                       foreach (var evt in GetEvents (bindingAttr)) {
+                               if (evt.Name == name)
+                                       return evt;
+                       }
+                       return null;
+               }
+
+               public override FieldInfo GetField( string name, BindingFlags bindingAttr)
+               {
+                       throw new NotSupportedException ();
+               }
+
+               public override MemberInfo[] GetMembers (BindingFlags bindingAttr)
+               {
+                       throw new NotSupportedException ();
+               }
+
+               public override Type GetNestedType (string name, BindingFlags bindingAttr)
+               {
+                       throw new NotSupportedException ();
+               }
+
+               public override object InvokeMember (string name, BindingFlags invokeAttr,
+                                                    Binder binder, object target, object[] args,
+                                                    ParameterModifier[] modifiers,
+                                                    CultureInfo culture, string[] namedParameters)
+               {
+                       throw new NotSupportedException ();
+               }
+
+               protected override MethodInfo GetMethodImpl (string name, BindingFlags bindingAttr, Binder binder,
+                                                            CallingConventions callConvention, Type[] types,
+                                                            ParameterModifier[] modifiers)
+               {
+                       throw new NotSupportedException ();
+               }
+
+               protected override PropertyInfo GetPropertyImpl (string name, BindingFlags bindingAttr, Binder binder,
+                                                                Type returnType, Type[] types, ParameterModifier[] modifiers)
+               {
+                       throw new NotSupportedException ();
+               }
+
+               protected override ConstructorInfo GetConstructorImpl (BindingFlags bindingAttr,
+                                                                      Binder binder,
+                                                                      CallingConventions callConvention,
+                                                                      Type[] types,
+                                                                      ParameterModifier[] modifiers)
+               {
+                       throw new NotSupportedException ();
+               }
+
+               //MemberInfo
+               public override bool IsDefined (Type attributeType, bool inherit)
+               {
+                       throw new NotSupportedException ();
+               }
+
+               public override object [] GetCustomAttributes (bool inherit)
+               {
+                       throw new NotSupportedException ();
+               }
+
+               public override object [] GetCustomAttributes (Type attributeType, bool inherit)
+               {
+                       throw new NotSupportedException ();
+               }
        }
 }
 
index 5407fcf4e300c49ae81bf527b36108039508a28c..3c9f712eb600d59b687ee37a4f700242e66f0646 100644 (file)
@@ -1,3 +1,7 @@
+2009-08-11  Jérémie Laval  <jeremie.laval@gmail.com>
+
+       * TypeForwardedFromAttribute.cs: Add BOOTSTRAP_NET_4_0.
+
 2009-07-02  Marek Safar  <marek.safar@gmail.com>
 
        * ConditionalWeakTable.cs: New file.
index 4d053dc67eb889336ca3ab9a323804875cfd6cf6..d5b48c6b454c494d974798bad6bed8be71adbb31 100644 (file)
@@ -26,7 +26,7 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-#if NET_4_0
+#if NET_4_0 || BOOTSTRAP_NET_4_0
 
 namespace System.Runtime.CompilerServices
 {
index 0004edea906fba2f93bd749dfb601df8de212181..b3783dfea02a80643b25d194080a1fc39eb37ebc 100644 (file)
@@ -1,3 +1,20 @@
+2009-08-19  Jérémie Laval  <jeremie.laval@gmail.com>
+
+       * Task.cs: Refactor Wait methods.
+
+2009-08-11  Jérémie Laval  <jeremie.laval@gmail.com>
+
+       * Future.cs: Add static to Factory property
+
+2009-08-11  Jérémie Laval  <jeremie.laval@gmail.com>
+
+       * Task.cs: Make WaitAny uses general continuation
+       framework.
+
+2009-08-11  Jérémie Laval  <jeremie.laval@gmail.com>
+
+       * TaskFactory.cs: Fix methods signature.
+
 2009-08-05  Jérémie Laval  <jeremie.laval@gmail.com>
 
        * Future.cs: Fix for Future, when using TaskCompletionSource
index 96a8a86f6dac70d0b20b8bbc8f78299c4ca3c94a..7930b85c40b8c64ffae87dccca220c4b07b1c48c 100644 (file)
@@ -31,7 +31,7 @@ namespace System.Threading.Tasks
        public class Task<TResult>: Task
        {
                TResult value;
-               TaskFactory<TResult> factory = new TaskFactory<TResult> ();
+               static TaskFactory<TResult> factory = new TaskFactory<TResult> ();
                
                Func<object, TResult> function;
                object state;
@@ -56,7 +56,7 @@ namespace System.Threading.Tasks
                        }
                }
                
-               public new TaskFactory<TResult> Factory {
+               public static TaskFactory<TResult> Factory {
                        get {
                                return factory;
                        }
index 54f85dbea1514da8c98da0beb4be47beb0c275cc..cf71851f3e9bab0a53d27a3bbb3dbe358fbd014b 100644 (file)
@@ -201,7 +201,7 @@ namespace System.Threading.Tasks
                }
                
                internal void ContinueWithCore (Task continuation, TaskContinuationOptions kind,
-                                                         TaskScheduler scheduler, Func<bool> predicate)
+                                               TaskScheduler scheduler, Func<bool> predicate)
                {
                        // Already set the scheduler so that user can call Wait and that sort of stuff
                        continuation.taskScheduler = scheduler;
@@ -455,22 +455,10 @@ namespace System.Threading.Tasks
                        if (exception != null && !(exception is TaskCanceledException))
                                throw exception;
                }
-               
-               [MonoTODO ("Refactor")]
+
                public void Wait (CancellationToken token)
                {
-                       if (scheduler == null)
-                               throw new InvalidOperationException ("The Task hasn't been Started and thus can't be waited on");
-                       
-                       Watch sw = Watch.StartNew ();
-                       scheduler.ParticipateUntil (this, delegate { 
-                               return token.IsCancellationRequested;
-                       });
-                       sw.Stop ();
-                       
-                       if (exception != null && !(exception is TaskCanceledException))
-                               throw exception;
-                       
+                       Wait (null, token);
                }
                
                public bool Wait (TimeSpan ts)
@@ -480,33 +468,29 @@ namespace System.Threading.Tasks
                
                public bool Wait (int millisecondsTimeout)
                {
-                       if (scheduler == null)
-                               throw new InvalidOperationException ("The Task hasn't been Started and thus can't be waited on");
-                       
                        Watch sw = Watch.StartNew ();
-                       bool result = scheduler.ParticipateUntil (this, delegate { 
-                               return sw.ElapsedMilliseconds >= millisecondsTimeout;
-                       });
-                       sw.Stop ();
-                       
-                       if (exception != null && !(exception is TaskCanceledException))
-                               throw exception;
-                       
-                       return !result;
+                       return Wait (() => sw.ElapsedMilliseconds >= millisecondsTimeout, null);
                }
                
-               [MonoTODO ("Refactor")]
                public bool Wait (int millisecondsTimeout, CancellationToken token)
+               {
+                       Watch sw = Watch.StartNew ();
+                       return Wait (() => sw.ElapsedMilliseconds >= millisecondsTimeout, token);
+               }
+
+               bool Wait (Func<bool> stopFunc, CancellationToken? token)
                {
                        if (scheduler == null)
                                throw new InvalidOperationException ("The Task hasn't been Started and thus can't be waited on");
                        
-                       Watch sw = Watch.StartNew ();
                        bool result = scheduler.ParticipateUntil (this, delegate { 
-                               return sw.ElapsedMilliseconds >= millisecondsTimeout || token.IsCancellationRequested;
+                               if (token.HasValue && token.Value.IsCancellationRequested)
+                                       throw new OperationCanceledException ("The CancellationToken has had cancellation requested.");
+                               
+                               
+                               return (stopFunc != null) ? stopFunc () : false;
                        });
-                       sw.Stop ();
-                       
+
                        if (exception != null && !(exception is TaskCanceledException))
                                throw exception;
                        
@@ -575,6 +559,11 @@ namespace System.Threading.Tasks
                }
                
                public static int WaitAny (params Task[] tasks)
+               {
+                       return WaitAny (tasks, null, null);
+               }
+               
+               static int WaitAny (Task[] tasks, Func<bool> stopFunc, CancellationToken? token)
                {
                        if (tasks == null)
                                throw new ArgumentNullException ("tasks");
@@ -586,22 +575,28 @@ namespace System.Threading.Tasks
                        int index = 0;
                        
                        foreach (Task t in tasks) {
-                               if (t.IsCompleted) {
-                                       return index;
-                               }
-                               t.completed += delegate (object sender, EventArgs e) {
+                               t.ContinueWith (delegate {
+                                       int indexResult = index;
                                        int result = Interlocked.Increment (ref numFinished);
                                        // Check if we are the first to have finished
-                                       if (result == 1) {
-                                               Task target = (Task)sender;
-                                               indexFirstFinished = Array.FindIndex (tasks, (elem) => elem == target);
-                                       }
-                               };      
+                                       if (result == 1)
+                                               indexFirstFinished = indexResult;
+                               });     
                                index++;
                        }
                        
+                       // One task already finished
+                       if (indexFirstFinished != -1)
+                               return indexFirstFinished;
+                       
                        // All tasks are supposed to use the same TaskManager
                        tasks[0].scheduler.ParticipateUntil (delegate {
+                               if (stopFunc != null && stopFunc ())
+                                       return true;
+                               
+                               if (token.HasValue && token.Value.IsCancellationRequested)
+                                       throw new OperationCanceledException ("The CancellationToken has had cancellation requested.");
+                               
                                return numFinished >= 1;
                        });
                        
@@ -617,107 +612,29 @@ namespace System.Threading.Tasks
                {
                        if (millisecondsTimeout < -1)
                                throw new ArgumentOutOfRangeException ("millisecondsTimeout");
-                       if (tasks == null)
-                               throw new ArgumentNullException ("tasks");
                        
                        if (millisecondsTimeout == -1)
                                return WaitAny (tasks);
                        
-                       int numFinished = 0;
-                       int indexFirstFinished = -1;
-                       
-                       foreach (Task t in tasks) {
-                               t.completed += delegate (object sender, EventArgs e) { 
-                                       int result = Interlocked.Increment (ref numFinished);
-                                       if (result == 1) {
-                                               Task target = (Task)sender;
-                                               indexFirstFinished = Array.FindIndex (tasks, (elem) => elem == target);
-                                       }
-                               };      
-                       }
-                       
                        Watch sw = Watch.StartNew ();
-                       tasks[0].scheduler.ParticipateUntil (delegate {
-                               if (sw.ElapsedMilliseconds > millisecondsTimeout)
-                                       return true;
-                               return numFinished >= 1;
-                       });
-                       sw.Stop ();
-                       
-                       return indexFirstFinished;
+                       return WaitAny (tasks, () => sw.ElapsedMilliseconds > millisecondsTimeout, null);
                }
-               
-               [MonoTODO ("Refactor")]
+
                public static int WaitAny (Task[] tasks, int millisecondsTimeout, CancellationToken token)
-               {
+               {                       
                        if (millisecondsTimeout < -1)
                                throw new ArgumentOutOfRangeException ("millisecondsTimeout");
-                       if (tasks == null)
-                               throw new ArgumentNullException ("tasks");
                        
                        if (millisecondsTimeout == -1)
                                return WaitAny (tasks);
                        
-                       int numFinished = 0;
-                       int indexFirstFinished = -1;
-                       
-                       foreach (Task t in tasks) {
-                               t.completed += delegate (object sender, EventArgs e) { 
-                                       int result = Interlocked.Increment (ref numFinished);
-                                       if (result == 1) {
-                                               Task target = (Task)sender;
-                                               indexFirstFinished = Array.FindIndex (tasks, (elem) => elem == target);
-                                       }
-                               };      
-                       }
-                       
                        Watch sw = Watch.StartNew ();
-                       tasks[0].scheduler.ParticipateUntil (delegate {
-                               if (sw.ElapsedMilliseconds > millisecondsTimeout || token.IsCancellationRequested)
-                                       return true;
-                               return numFinished >= 1;
-                       });
-                       sw.Stop ();
-                       
-                       return indexFirstFinished;
+                       return WaitAny (tasks, () => sw.ElapsedMilliseconds > millisecondsTimeout, token);
                }
                
-               [MonoTODO ("Refactor")]
                public static int WaitAny (Task[] tasks, CancellationToken token)
-               {
-                       if (tasks == null)
-                               throw new ArgumentNullException ("tasks");
-                       if (tasks.Length == 0)
-                               throw new ArgumentException ("tasks is empty", "tasks");
-                       
-                       int numFinished = 0;
-                       int indexFirstFinished = -1;
-                       int index = 0;
-                       
-                       foreach (Task t in tasks) {
-                               if (t.IsCompleted) {
-                                       return index;
-                               }
-                               t.completed += delegate (object sender, EventArgs e) {
-                                       int result = Interlocked.Increment (ref numFinished);
-                                       // Check if we are the first to have finished
-                                       if (result == 1) {
-                                               Task target = (Task)sender;
-                                               indexFirstFinished = Array.FindIndex (tasks, (elem) => elem == target);
-                                       }
-                               };      
-                               index++;
-                       }
-                       
-                       // All tasks are supposed to use the same TaskManager
-                       tasks[0].scheduler.ParticipateUntil (delegate {
-                               if (token.IsCancellationRequested)
-                                       return true;
-                               
-                               return numFinished >= 1;
-                       });
-                       
-                       return indexFirstFinished;
+               {                       
+                       return WaitAny (tasks, null, token);
                }
                #endregion
                
index c15389f00a45b222237c3d8eda18f1696adb361d..536b9ada202abff75c4ec2d05c224d3369ad9ed7 100644 (file)
@@ -146,9 +146,9 @@ namespace System.Threading.Tasks
 
                [MonoTODO]
                public Task ContinueWhenAny (Task[] tasks, Action<Task> continuationAction, TaskContinuationOptions continuationOptions,
-                                           TaskScheduler scheduler)
+                                            TaskScheduler scheduler)
                {
-                 return null;
+                       throw new NotImplementedException ();
                }
                
                [MonoTODO]
@@ -159,7 +159,7 @@ namespace System.Threading.Tasks
                
                [MonoTODO]
                public Task<TResult> ContinueWhenAny<TResult> (Task[] tasks, Func<Task, TResult> continuationAction,
-                                                     TaskContinuationOptions continuationOptions)
+                                                              TaskContinuationOptions continuationOptions)
                {
                        return ContinueWhenAny (tasks, continuationAction, continuationOptions, scheduler);
                }
@@ -169,7 +169,7 @@ namespace System.Threading.Tasks
                                                               TaskContinuationOptions continuationOptions,
                                                               TaskScheduler scheduler)
                {
-                       return null;
+                       throw new NotImplementedException ();
                }
                
                public Task ContinueWhenAll (Task[] tasks, Action<Task[]> continuationFunction)
@@ -469,7 +469,7 @@ namespace System.Threading.Tasks
                }
                
                public Task<TResult> StartNew (Func<object, TResult> function, object state, TaskCreationOptions options,
-                                                       TaskScheduler scheduler)
+                                              TaskScheduler scheduler)
                {
                        return parent.StartNew<TResult> (function, state, options, scheduler);
                }
@@ -494,28 +494,28 @@ namespace System.Threading.Tasks
                                             TaskContinuationOptions continuationOptions,
                                             TaskScheduler scheduler)
                {
-                 return null;
+                       throw new NotImplementedException ();
                }
                
                [MonoTODO]
-               public Task<TNewResult> ContinueWhenAny<TNewResult> (Task<TResult>[] tasks, Func<Task, TNewResult> continuationAction)
+               public Task<TNewResult> ContinueWhenAny<TNewResult> (Task<TResult>[] tasks, Func<Task<TResult>, TNewResult> continuationAction)
                {
                        return ContinueWhenAny (tasks, continuationAction, contOptions);
                }
                
                [MonoTODO]
-               public Task<TNewResult> ContinueWhenAny<TNewResult> (Task<TResult>[] tasks, Func<Task, TNewResult> continuationAction,
-                                                     TaskContinuationOptions continuationOptions)
+               public Task<TNewResult> ContinueWhenAny<TNewResult> (Task<TResult>[] tasks, Func<Task<TResult>, TNewResult> continuationAction,
+                                                                    TaskContinuationOptions continuationOptions)
                {
                        return ContinueWhenAny (tasks, continuationAction, continuationOptions, scheduler);
                }
 
                [MonoTODO]
-               public Task<TNewResult> ContinueWhenAny<TNewResult> (Task<TResult>[] tasks, Func<Task, TNewResult> continuationAction,
-                                                              TaskContinuationOptions continuationOptions,
-                                                              TaskScheduler scheduler)
+               public Task<TNewResult> ContinueWhenAny<TNewResult> (Task<TResult>[] tasks, Func<Task<TResult>, TNewResult> continuationAction,
+                                                                    TaskContinuationOptions continuationOptions,
+                                                                    TaskScheduler scheduler)
                {
-                       return null;
+                       throw new NotImplementedException ();
                }
                
                public Task ContinueWhenAll (Task<TResult>[] tasks, Action<Task<TResult>[]> continuationFunction)
@@ -542,20 +542,20 @@ namespace System.Threading.Tasks
                }
                
                public Task<TNewResult> ContinueWhenAll<TNewResult> (Task<TResult>[] tasks,
-                                                                    Func<Task<TNewResult>[], TNewResult> continuationFunction)
+                                                                    Func<Task<TResult>[], TNewResult> continuationFunction)
                {
                        return ContinueWhenAll (tasks, continuationFunction, contOptions);
                }
                
                public Task<TNewResult> ContinueWhenAll<TNewResult> (Task<TResult>[] tasks,
-                                                                    Func<Task<TNewResult>[], TNewResult> continuationFunction,
+                                                                    Func<Task<TResult>[], TNewResult> continuationFunction,
                                                                     TaskContinuationOptions continuationOptions)
                {
                        return ContinueWhenAll (tasks, continuationFunction, continuationOptions, scheduler);
                }
                
                public Task<TNewResult> ContinueWhenAll<TNewResult> (Task<TResult>[] tasks,
-                                                                    Func<Task<TNewResult>[], TNewResult> continuationFunction,
+                                                                    Func<Task<TResult>[], TNewResult> continuationFunction,
                                                                     TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
                {
                        CountdownEvent evt = new CountdownEvent (tasks.Length);
diff --git a/mcs/class/corlib/System.Threading/AggregateException.cs b/mcs/class/corlib/System.Threading/AggregateException.cs
deleted file mode 100644 (file)
index be96d1b..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-#if NET_4_0
-// AggregateException.cs
-//
-// Copyright (c) 2008 Jérémie "Garuma" Laval
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-//
-
-using System;
-using System.Collections.ObjectModel;
-using System.Collections.Generic;
-using System.Runtime.Serialization;
-
-namespace System.Threading
-{
-       [System.SerializableAttribute]
-       public class AggregateException : Exception
-       {
-               List<Exception> innerExceptions;
-               
-               public AggregateException (): base()
-               {
-               }
-               
-               public AggregateException (string message): base (message, null)
-               {
-               }
-               
-               public AggregateException (string message, Exception e): base (message, e)
-               {
-               }
-               
-               public AggregateException (SerializationInfo info, StreamingContext ctx)
-                       : base (info, ctx)
-               {
-               }
-               
-               public AggregateException (params Exception[] innerExceptions)
-                       : this (string.Empty, innerExceptions)
-               {
-               }
-               
-               public AggregateException (string message, params Exception[] innerExceptions)
-                       : this (message, (IEnumerable<Exception>)innerExceptions)
-               {
-               }
-               
-               public AggregateException (IEnumerable<Exception> innerExceptions)
-                       : this (string.Empty, innerExceptions)
-               {
-               }
-               
-               public AggregateException (string message, IEnumerable<Exception> inner)
-                       : base(GetFormattedMessage(message, inner))
-               {
-                       this.innerExceptions = new List<Exception> (inner);
-               }
-               
-               public AggregateException Flatten ()
-               {
-                       List<Exception> inner = new List<Exception> ();
-                       
-                       foreach (Exception e in innerExceptions) {
-                               AggregateException aggEx = e as AggregateException;
-                               if (aggEx != null) {
-                                       inner.AddRange (aggEx.Flatten ().InnerExceptions);
-                               } else {
-                                       inner.Add (e);
-                               }                               
-                       }
-
-                       return new AggregateException (inner);
-               }
-               
-               public void Handle (Func<Exception, bool> handler)
-               {
-                       List<Exception> failed = new List<Exception> ();
-                       foreach (var e in innerExceptions) {
-                               try {
-                                       if (!handler (e))
-                                               failed.Add (e);
-                               } catch {
-                                       throw new AggregateException (failed);
-                               }
-                       }
-                       if (failed.Count > 0)
-                               throw new AggregateException (failed);
-               }
-               
-               public ReadOnlyCollection<Exception> InnerExceptions {
-                       get {
-                               return innerExceptions.AsReadOnly ();
-                       }
-               }
-               
-               public override string ToString ()
-               {
-                       return this.Message;
-               }
-               
-               const string baseMessage = "Exception(s) occurred while inside the Parallel loop. {0}.";
-               static string GetFormattedMessage (string customMessage, IEnumerable<Exception> inner)
-               {
-                       System.Text.StringBuilder finalMessage
-                               = new System.Text.StringBuilder (string.Format (baseMessage, customMessage));
-                       foreach (Exception e in inner) {
-                               finalMessage.Append (Environment.NewLine);
-                               finalMessage.Append ("[ ");
-                               finalMessage.Append (e.ToString ());
-                               finalMessage.Append (" ]");
-                               finalMessage.Append (Environment.NewLine);
-                       }
-                       return finalMessage.ToString ();
-               }
-       }
-}
-#endif
index 4195fca3a55fef46fd03e49d7ce74903b006c1c7..c91bde8ec16f5650bac2bc459ddbc16ff5cfc9f7 100644 (file)
@@ -27,7 +27,7 @@ using System;
 
 namespace System.Threading
 {
-       internal struct AtomicBoolean
+       internal class AtomicBoolean
        {
                int flag;
                const int UnSet = 0;
@@ -49,6 +49,11 @@ namespace System.Threading
                        return temp;
                }
                
+               public bool TrySet ()
+               {
+                       return !Exchange (true);
+               }
+               
                public bool Exchange (bool newVal)
                {
                        int newTemp = newVal ? Set : UnSet;
diff --git a/mcs/class/corlib/System.Threading/Barrier.cs b/mcs/class/corlib/System.Threading/Barrier.cs
deleted file mode 100644 (file)
index 6642f0c..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-#if NET_4_0
-// 
-// Barrier.cs
-//  
-// Author:
-//       Jérémie "Garuma" Laval <jeremie.laval@gmail.com>
-// 
-// Copyright (c) 2009 Jérémie "Garuma" Laval
-// 
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-// 
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-using System;
-
-namespace System.Threading
-{
-       public class Barrier
-       {
-               readonly Action<Barrier> postPhaseAction;
-               
-               int participants;
-               CountdownEvent cntd;
-               int phase;
-
-               public Barrier (int participants) : this (participants, null)
-               {
-               }
-               
-               public Barrier (int participants, Action<Barrier> postPhaseAction)
-               {
-                       this.participants = participants;
-                       this.postPhaseAction = postPhaseAction;
-                       
-                       InitCountdownEvent ();
-               }
-               
-               void InitCountdownEvent ()
-               {
-                       cntd = new CountdownEvent (participants);
-               }
-               
-               public int AddParticipant ()
-               {
-                       return AddParticipants (1);
-               }
-               
-               public int AddParticipants (int participantCount)
-               {
-                       // Basically, we try to add ourselves and return
-                       // the phase. If the call return false, we repeatdly try
-                       // to add ourselves for the next phase
-                       do {
-                               if (cntd.TryAddCount (participantCount)) {
-                                       Interlocked.Add (ref participants, participantCount);
-                                       return phase;
-                               }
-                       } while (true);
-               }
-               
-               public void RemoveParticipant ()
-               {
-                       RemoveParticipants (1);
-               }
-               
-               public void RemoveParticipants (int participantCount)
-               {
-                       cntd.Signal (participantCount);
-                       Interlocked.Add (ref participants, -participantCount);
-               }
-               
-               public void SignalAndWait ()
-               {
-                       SignalAndWait (() => { cntd.Wait (); return true; });
-               }
-               
-               public bool SignalAndWait (int millisecondTimeout)
-               {
-                       return SignalAndWait (() => cntd.Wait (millisecondTimeout));
-               }
-               
-               public bool SignalAndWait (TimeSpan ts)
-               {
-                       return SignalAndWait (() => cntd.Wait (ts));
-               }
-               
-               public bool SignalAndWait (int millisecondTimeout, CancellationToken token)
-               {
-                       return SignalAndWait (() => cntd.Wait (millisecondTimeout, token));
-               }
-               
-               public bool SignalAndWait (TimeSpan ts, CancellationToken token)
-               {
-                       return SignalAndWait (() => cntd.Wait (ts, token));
-               }
-               
-               bool SignalAndWait (Func<bool> associate)
-               {
-                       bool result;
-                       
-                       if (!cntd.Signal ()) {
-                               result = associate ();
-                       } else {
-                               result = true;
-                               postPhaseAction (this);
-                               phase++;
-                       }
-                       
-                       return result;
-               }
-               
-               public int CurrentPhaseNumber {
-                       get {
-                               return phase;
-                       }
-               }
-               
-               public int ParticipantCount  {
-                       get {
-                               return participants;
-                       }
-               }
-       }
-}
-#endif
index f54c0b29ff288cff4819c70cc157d666f8c0cd58..1c67aa071ed4e7b711865eece2f47f8c628f3148 100644 (file)
@@ -1,4 +1,4 @@
-#if NET_4_0
+#if NET_4_0 || BOOTSTRAP_NET_4_0
 // 
 // CancellationToken.cs
 //  
index 5d0b05f48cf7be09f255b2fb9be33c0392afdd76..e12f9c9e23ac3e0b8ee3e537cf4a61d2c3ed265b 100644 (file)
@@ -1,4 +1,4 @@
-#if NET_4_0
+#if NET_4_0 || BOOTSTRAP_NET_4_0
 // 
 // CancellationTokenRegistration.cs
 //  
index 872e4be3a9d73ab4dbb1f5e43f909283c72d3201..dc0f7ef0d0e6e5b88dd5249122107e744536864c 100644 (file)
@@ -1,4 +1,4 @@
-#if NET_4_0
+#if NET_4_0 || BOOTSTRAP_NET_4_0
 // 
 // CancellationTokenSource.cs
 //  
index 53223eac2570dec3600bd453533c5bd5d58a8012..c4277fee3e3333b58f125facb42c462d9ee9225a 100644 (file)
@@ -1,3 +1,31 @@
+2009-08-19  Jérémie Laval  <jeremie.laval@gmail.com>
+
+       * ParallelLoopState.cs: Take in account that
+       AtomicBoolean is a class.
+
+2009-08-19  Jérémie Laval  <jeremie.laval@gmail.com>
+
+       * AtomicBoolean.cs: Turn it into a class
+       * CountdownEvent.cs: Work on cached variable. Make sure
+       count doesn't go under 0.
+
+2009-08-11  Jérémie Laval  <jeremie.laval@gmail.com>
+
+       * Watch.cs:
+       * SpinWait.cs:
+       * CountdownEvent.cs:
+       * CancellationToken.cs:
+       * ICancelableOperation.cs:
+       * CancellationTokenSource.cs:
+       * CancellationTokenRegistration.cs: Add BOOTSTRAP_NET_4_0.
+
+2009-08-11  Jérémie Laval  <jeremie.laval@gmail.com>
+
+       * Parallel.cs: Disable While method.
+       * CountdownEvent.cs: Fix method signature.
+       * Barrier.cs: Moved type.
+       * AggregateException.cs: Moved type.
+
 2009-08-04 Jérémie Laval  <jeremie.laval@gmail.com>
 
        * SpinLock: Remove unused private methods.
@@ -16,7 +44,7 @@
         * ThreadLocal.cs:
         * SemaphoreSlim.cs:
         * CountdownEvent.cs:
-        * ManualResetEventSlim.cs:
+        * ManualResetEventSlim.cs
         * CancellationTokenSource.cs: Various 4.0 b1 API mismatch fixes.
 
 2009-07-30 Jérémie Laval  <jeremie.laval@gmail.com>
index 156b8f431c5ba61612299d9e3b3a2fb1fc317a71..0a53f30e5244c7124dcae24597c67345aba019a3 100644 (file)
@@ -1,4 +1,4 @@
-#if NET_4_0
+#if NET_4_0 || BOOTSTRAP_NET_4_0
 // CountdownEvent.cs
 //
 // Copyright (c) 2008 Jérémie "Garuma" Laval
@@ -47,7 +47,7 @@ namespace System.Threading
                
                public bool Signal (int num)
                {
-                       if (num < 0)
+                       if (num <= 0)
                                throw new ArgumentOutOfRangeException ("num");
                        
                        Action<int> check = delegate (int value) {
@@ -59,7 +59,7 @@ namespace System.Threading
                        if (!ApplyOperation (-num, check, out newValue))
                                throw new InvalidOperationException ("The event is already set");
                        
-                       if (newValue <= 0) {
+                       if (newValue == 0) {
                                evt.Set ();
                                return true;
                        }
@@ -91,9 +91,7 @@ namespace System.Threading
                        if (num < 0)
                                throw new ArgumentOutOfRangeException ("num");
                        
-                       Action<int> check = delegate (int value) {      };
-                       
-                       return ApplyOperation (num, check);
+                       return ApplyOperation (num, null);
                }
                
                bool ApplyOperation (int num, Action<int> doCheck)
@@ -108,14 +106,14 @@ namespace System.Threading
                        newValue = 0;
                        
                        do {
-                               if (IsSet)
+                               oldCount = count;
+                               if (oldCount == 0)
                                        return false;
                                
-                               oldCount = count;
                                newValue = oldCount + num;
                                
-                               doCheck (newValue);
-                               
+                               if (doCheck != null)
+                                       doCheck (newValue);
                        } while (Interlocked.CompareExchange (ref count, newValue, oldCount) != oldCount);
                        
                        return true;
@@ -129,9 +127,9 @@ namespace System.Threading
                        }
                }
                
-               public bool Wait (CancellationToken token)
+               public void Wait (CancellationToken token)
                {
-                       return Wait (() => token.IsCancellationRequested);
+                       Wait (() => token.IsCancellationRequested);
                }
                
                public bool Wait (int timeoutMilli)
@@ -214,7 +212,7 @@ namespace System.Threading
                        
                public bool IsSet {
                        get {
-                               return count <= 0;
+                               return count == 0;
                        }
                }
                
index 1a17a035d31005e1686c39e82353579182a63cc4..e1115e265cddb37d7fdf69666884ac68453e132e 100644 (file)
@@ -1,4 +1,4 @@
-#if NET_4_0
+#if NET_4_0 || BOOTSTRAP_NET_4_0
 // 
 // ICancelableOperation.cs
 //  
index 953a952a02f6bf357c976defbcdd42ac16b1483b..5aa9a30db3e1de25002ac580c83052045d6d0f5a 100644 (file)
@@ -428,6 +428,7 @@ namespace System.Threading
                }
                #endregion
                
+               /* Disabled as this is an API addition
                #region While           
                public static void While (Func<bool> predicate, Action body)
                {
@@ -451,6 +452,7 @@ namespace System.Threading
                }
                
                #endregion
+               */
 
                #region Invoke
                public static void Invoke (params Action[] actions)
index 8231aaa9fb93c8ba850919149189895c90556ad3..da75feade4a20de2911ba2d4edb109213b2af0d4 100644 (file)
@@ -32,8 +32,8 @@ namespace System.Threading
        {
                internal class ExternalInfos
                {
-                       public AtomicBoolean IsStopped;
-                       public AtomicBoolean IsBroken;
+                       public AtomicBoolean IsStopped = new AtomicBoolean ();
+                       public AtomicBoolean IsBroken = new AtomicBoolean ();
                        public volatile bool IsExceptional;
                        public long? LowestBreakIteration;
                }
index bb5ddcf1456220e3f504471b080f228bd01367ca..001891bbe6c70011becaaf3b23b52dc65e8c0b56 100644 (file)
@@ -1,4 +1,4 @@
-#if NET_4_0
+#if NET_4_0 || BOOTSTRAP_NET_4_0
 // SpinWait.cs
 //
 // Copyright (c) 2008 Jérémie "Garuma" Laval
index fe61efc28363171dbe2875875674b4d93d89cfbd..8c0caf462d730a1295753287dbbed36ba16acd11 100644 (file)
@@ -1,4 +1,4 @@
-#if NET_4_0
+#if NET_4_0 || BOOTSTRAP_NET_4_0
 // Task.cs
 //
 // Copyright (c) 2008 Jérémie "Garuma" Laval
index 31f076f48d7f705373917534401509601d755b6d..2fa759ec0ef2382ec8264e0ddc949df80c203709 100644 (file)
@@ -31,7 +31,7 @@ using System.Runtime.CompilerServices;
 
 namespace System
 {
-#if NET_4_0
+#if NET_4_0 || BOOTSTRAP_NET_4_0
        [TypeForwardedFrom (Consts.AssemblySystemCore_3_5)]
        public delegate void Action ();
        
diff --git a/mcs/class/corlib/System/AggregateException.cs b/mcs/class/corlib/System/AggregateException.cs
new file mode 100644 (file)
index 0000000..9fd89eb
--- /dev/null
@@ -0,0 +1,134 @@
+#if NET_4_0 || BOOTSTRAP_NET_4_0
+// AggregateException.cs
+//
+// Copyright (c) 2008 Jérémie "Garuma" Laval
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+//
+
+using System;
+using System.Collections.ObjectModel;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace System
+{
+       [System.SerializableAttribute]
+       public class AggregateException : Exception
+       {
+               List<Exception> innerExceptions;
+               
+               public AggregateException (): base()
+               {
+               }
+               
+               public AggregateException (string message): base (message, null)
+               {
+               }
+               
+               public AggregateException (string message, Exception e): base (message, e)
+               {
+               }
+               
+               public AggregateException (SerializationInfo info, StreamingContext ctx)
+                       : base (info, ctx)
+               {
+               }
+               
+               public AggregateException (params Exception[] innerExceptions)
+                       : this (string.Empty, innerExceptions)
+               {
+               }
+               
+               public AggregateException (string message, params Exception[] innerExceptions)
+                       : this (message, (IEnumerable<Exception>)innerExceptions)
+               {
+               }
+               
+               public AggregateException (IEnumerable<Exception> innerExceptions)
+                       : this (string.Empty, innerExceptions)
+               {
+               }
+               
+               public AggregateException (string message, IEnumerable<Exception> inner)
+                       : base(GetFormattedMessage(message, inner))
+               {
+                       this.innerExceptions = new List<Exception> (inner);
+               }
+               
+               public AggregateException Flatten ()
+               {
+                       List<Exception> inner = new List<Exception> ();
+                       
+                       foreach (Exception e in innerExceptions) {
+                               AggregateException aggEx = e as AggregateException;
+                               if (aggEx != null) {
+                                       inner.AddRange (aggEx.Flatten ().InnerExceptions);
+                               } else {
+                                       inner.Add (e);
+                               }                               
+                       }
+
+                       return new AggregateException (inner);
+               }
+               
+               public void Handle (Func<Exception, bool> handler)
+               {
+                       List<Exception> failed = new List<Exception> ();
+                       foreach (var e in innerExceptions) {
+                               try {
+                                       if (!handler (e))
+                                               failed.Add (e);
+                               } catch {
+                                       throw new AggregateException (failed);
+                               }
+                       }
+                       if (failed.Count > 0)
+                               throw new AggregateException (failed);
+               }
+               
+               public ReadOnlyCollection<Exception> InnerExceptions {
+                       get {
+                               return innerExceptions.AsReadOnly ();
+                       }
+               }
+               
+               public override string ToString ()
+               {
+                       return this.Message;
+               }
+               
+               const string baseMessage = "Exception(s) occurred while inside the Parallel loop. {0}.";
+               static string GetFormattedMessage (string customMessage, IEnumerable<Exception> inner)
+               {
+                       System.Text.StringBuilder finalMessage
+                               = new System.Text.StringBuilder (string.Format (baseMessage, customMessage));
+                       foreach (Exception e in inner) {
+                               finalMessage.Append (Environment.NewLine);
+                               finalMessage.Append ("[ ");
+                               finalMessage.Append (e.ToString ());
+                               finalMessage.Append (" ]");
+                               finalMessage.Append (Environment.NewLine);
+                       }
+                       return finalMessage.ToString ();
+               }
+       }
+}
+#endif
index c26c3f3a4e0920f7ae3a7e978783a11f21ba4b0f..24a42659ba102cd0dd0d9cde7790628c5b4ede27 100644 (file)
@@ -1,3 +1,17 @@
+2009-08-14  Marek Safar  <marek.safar@gmail.com>
+
+       * Type.cs: Made IsClass work under compiler context.
+
+2009-08-12  Zoltan Varga  <vargaz@gmail.com>
+
+       * ResolveEventArgs.cs: Add net 4.0 RequestingAssembly property.
+
+2009-08-11  Jérémie Laval  <jeremie.laval@gmail.com>
+
+       * Funcs.cs:
+       * Action.cs:
+       * AggregateException.cs: Add BOOTSTRAP_NET_4_0.
+
 2009-08-07  Marek Safar  <marek.safar@gmail.com>
 
        * AppDomain.cs: IsHomogenous always returns true for now.
index b77d439a7c21f7a502681794752d4034452f89f9..ab5a960b4fb974dfa243ca8365dec2622f386566 100644 (file)
@@ -25,7 +25,7 @@
 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 //
 
-#if NET_4_0
+#if NET_4_0 || BOOTSTRAP_NET_4_0
 
 using System.Runtime.CompilerServices;
 
index dc4d54f400b84c0294eb1336920f9a28c16f8b3e..cc38186b1c079afc7037bbe360f7d50d5b36400c 100644 (file)
@@ -30,6 +30,7 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 using System.Runtime.InteropServices;
+using System.Reflection;
 
 namespace System
 {
@@ -39,16 +40,34 @@ namespace System
        public class ResolveEventArgs : EventArgs
        {
                private string m_Name;
+#if NET_4_0
+               private Assembly m_Requesting;
+#endif
 
                public ResolveEventArgs (string name)
                {
                        m_Name = name;
                }
 
+#if NET_4_0
+               public ResolveEventArgs (string name, Assembly requestingAssembly) {
+                       this.m_Name = name;
+                       this.m_Requesting = requestingAssembly;
+               }
+#endif
+
                public string Name {
                        get {
                                return m_Name;
                        }
                }
+
+#if NET_4_0
+               public Assembly RequestingAssembly {
+                       get {
+                               return m_Requesting;
+                       }
+               }
+#endif
        }
 }
index 79fe0ed56bdf2e3dec211eb3f4d6d00113ae244c..4c5e9608cc7b7f643851da161086ba8c95d4d39e 100644 (file)
@@ -112,4 +112,4 @@ namespace System
        }               
 }
        
-#endif
\ No newline at end of file
+#endif
index 2baefafe119b73fa559f43c71eea30637511466c..9e5fd9f905590e0268e73ce11c9b41dd620de425 100644 (file)
@@ -211,7 +211,7 @@ namespace System {
                                if (IsInterface)
                                        return false;
 
-                               return !IsSubclassOf (typeof (ValueType));
+                               return !IsValueType;
                        }
                }
 
diff --git a/mcs/class/corlib/Test/System.Collections.Concurrent/BlockingCollectionTests.cs b/mcs/class/corlib/Test/System.Collections.Concurrent/BlockingCollectionTests.cs
deleted file mode 100644 (file)
index 068ec16..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-#if NET_4_0
-// BlockingCollectionTests.cs
-//
-// Copyright (c) 2008 Jérémie "Garuma" Laval
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-//
-
-using System;
-using System.Threading;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-
-using NUnit.Framework;
-
-namespace ParallelFxTests
-{
-       [TestFixture()]
-       public class BlockingCollectionTests
-       {
-               BlockingCollection<int> defaultCollection;
-               BlockingCollection<int> boundedCollection;
-               
-               [SetUpAttribute]
-               public void Setup()
-               {
-                       defaultCollection = new BlockingCollection<int>();
-                       boundedCollection = new BlockingCollection<int>(10);
-               }
-               
-               [TestAttribute]
-               public void DefaultAddTestCase()
-               {
-                       defaultCollection.Add(1);
-                       defaultCollection.Add(2);
-                       Assert.AreEqual(2, defaultCollection.Count, "#1");
-
-               }
-               
-               [TestAttribute]
-               public void BoundedAddTestCase()
-               {
-                       boundedCollection.Add(1);
-                       boundedCollection.Add(2);
-                       Assert.AreEqual(2, boundedCollection.Count, "#1");
-               }
-               
-               [TestAttribute]
-               public void BoundedIsFullTestCase()
-               {
-                       boundedCollection.Add(1);
-                       boundedCollection.Add(2);
-                       boundedCollection.Add(3);
-                       boundedCollection.Add(4);
-                       boundedCollection.Add(5);
-                       boundedCollection.Add(6);
-                       boundedCollection.Add(7);
-                       boundedCollection.Add(8);
-                       boundedCollection.Add(9);
-                       boundedCollection.Add(10);
-                       Assert.AreEqual(boundedCollection.BoundedCapacity, boundedCollection.Count, "#1");
-               }
-               
-               [TestAttribute]
-               public void RemoveTestCase()
-               {
-                       defaultCollection.Add(1);
-                       defaultCollection.Add(2);
-                       boundedCollection.Add(1);
-                       boundedCollection.Add(2);
-                       
-                       int value = defaultCollection.Remove();
-                       Assert.AreEqual(1, value, "#1");
-                       value = boundedCollection.Remove();
-                       Assert.AreEqual(1, value, "#2");
-               }
-               
-               [TestAttribute, ExpectedExceptionAttribute(typeof(InvalidOperationException))]
-               public void DefaultAddCompletedTestCase()
-               {
-                       defaultCollection.Add(1);
-                       defaultCollection.Add(2);
-                       defaultCollection.CompleteAdding();
-                       Assert.IsTrue(defaultCollection.IsAddingCompleted, "#1");
-                       
-                       defaultCollection.Add(3);
-               }
-               
-               [TestAttribute, ExpectedExceptionAttribute(typeof(InvalidOperationException))]
-               public void BoundedAddCompletedTestCase()
-               {
-                       boundedCollection.Add(1);
-                       boundedCollection.Add(2);
-                       boundedCollection.Add(3);
-                       boundedCollection.Add(4);
-                       boundedCollection.Add(5);
-                       boundedCollection.Add(6);
-                       boundedCollection.Add(7);
-                       boundedCollection.Add(8);
-                       boundedCollection.Add(9);
-                       boundedCollection.Add(10);
-                       boundedCollection.CompleteAdding();
-                       Assert.IsTrue(boundedCollection.IsAddingCompleted, "#1");
-                       
-                       boundedCollection.Add(3);
-               }
-               
-               [TestAttribute]
-               public void IsCompletedTestCase()
-               {
-                       defaultCollection.Add(1);
-                       defaultCollection.Add(2);
-                       
-                       defaultCollection.CompleteAdding();
-                       Assert.IsFalse(defaultCollection.IsCompleted, "#3");
-                       
-                       defaultCollection.Remove();
-                       defaultCollection.Remove();
-                       
-                       Assert.IsTrue(defaultCollection.IsAddingCompleted, "#1");
-                       Assert.AreEqual(0, defaultCollection.Count, "#2");
-                       Assert.IsTrue(defaultCollection.IsCompleted, "#4");
-               }
-               
-               [TestAttribute]
-               public void ConsumingEnumerableTestCase()
-               {
-                       defaultCollection.Add(1);
-                       defaultCollection.Add(2);
-                       defaultCollection.Add(3);
-                       defaultCollection.Add(4);
-                       defaultCollection.Add(5);
-                       defaultCollection.Add(6);
-                       
-                       IEnumerable<int> enumerable = defaultCollection.GetConsumingEnumerable();
-                       Assert.IsNotNull(enumerable, "#1");
-                       int i = 1;
-                       foreach (int j in enumerable) {
-                               int temp = i++;
-                               Assert.AreEqual(temp, j, "#" + temp);
-                       }
-                       Assert.AreEqual(0, defaultCollection.Count, "#" + i);
-               }
-       }
-}
-#endif
index 5d4a31e68084f737969eef29ba422e9c3e3372eb..a7bf63a2bf97aa34efa49b1e36aee9f529d75722 100644 (file)
@@ -1,3 +1,7 @@
+2009-08-11  Jérémie Laval  <jeremie.laval@gmail.com>
+
+       * BlockingCollectionTests.cs: Moved file.
+
 2009-08-05  Jérémie Laval  <jeremie.laval@gmail.com>
 
        * ConcurrentDictionaryTests.cs: Re-enable ConcurrentDictionary unit
index 2cd097e88558999b00587202bc82f9fb6e56b104..03b789c8e434f44d05f3be493517ba8fac01bc05 100644 (file)
@@ -1,3 +1,8 @@
+2009-08-07 Rodrigo Kumpera  <rkumpera@novell.com>
+
+       * MonoGenericClassTest.cs: Test for methods that must
+       throw.
+
 2009-08-04 Rodrigo Kumpera  <rkumpera@novell.com>
 
        * MonoGenericClassTest.cs: New file.
index a5fef620d4216854f5891d54551a14bf941cbfdf..9babc60322238dfc301926398430620a4d4df0df 100644 (file)
@@ -39,14 +39,19 @@ namespace MonoTests.System.Reflection.Emit
                }
 
                [SetUp]
-               protected void SetUp ()
+               public void SetUp ()
+               {
+                       SetUp (AssemblyBuilderAccess.RunAndSave);
+               }
+               
+               void SetUp (AssemblyBuilderAccess access)
                {
                        AssemblyName assemblyName = new AssemblyName ();
                        assemblyName.Name = ASSEMBLY_NAME;
 
                        assembly =
                                Thread.GetDomain ().DefineDynamicAssembly (
-                                       assemblyName, AssemblyBuilderAccess.RunAndSave, Path.GetTempPath ());
+                                       assemblyName, access, Path.GetTempPath ());
 
                        module = assembly.DefineDynamicModule ("module1");
                        typeCount = 0;
@@ -67,6 +72,85 @@ namespace MonoTests.System.Reflection.Emit
                        Assert.AreEqual ("foo.type[[System.Double, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], MonoTests.System.Reflection.Emit.MonoGenericClassTest, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", inst.AssemblyQualifiedName, "#4");
                        Assert.AreEqual ("foo.type[System.Double,System.String]", inst.ToString (), "#5");
                }
+
+               [Test]
+               [Category ("NotDotNet")]
+               public void GetEventMustWorkUnderCompilerContext ()
+               {
+                       SetUp (AssemblyBuilderAccess.RunAndSave | (AssemblyBuilderAccess)0x800);
+                       var tb = module.DefineType ("foo.type");
+                       tb.DefineGenericParameters ("T");
+
+                       var ginst = tb.MakeGenericType (typeof (double));
+                       
+                       try {
+                               ginst.GetEvent ("foo", BindingFlags.Public | BindingFlags.Instance);
+                       } catch (NotSupportedException) {
+                               Assert.Fail ("#1");
+                       }
+               }
+
+               [Test]
+               public void MethodsThatRaiseNotSupported ()
+               {
+                       var tb = module.DefineType ("foo.type");
+                       tb.DefineGenericParameters ("T");
+
+                       var ginst = tb.MakeGenericType (typeof (double));
+
+                       /*try { //FIXME this doesn't work yet
+                               ginst.GetElementType ();
+                               Assert.Fail ("#1");
+                       } catch (NotSupportedException) {  }*/
+                       try {
+                               ginst.GetInterface ("foo", true);
+                               Assert.Fail ("#2");
+                       } catch (NotSupportedException) {  }
+                       try {
+                               ginst.GetEvent ("foo", BindingFlags.Public | BindingFlags.Instance);
+                               Assert.Fail ("#3");
+                       } catch (NotSupportedException) {  }
+                       try {
+                               ginst.GetField ("foo", BindingFlags.Public | BindingFlags.Instance);
+                               Assert.Fail ("#4");
+                       } catch (NotSupportedException) {  }
+                       try {
+                               ginst.GetMembers (BindingFlags.Public | BindingFlags.Instance);
+                               Assert.Fail ("#5");
+                       } catch (NotSupportedException) {  }
+                       try {
+                               ginst.GetMethod ("Foo");
+                               Assert.Fail ("#6");
+                       } catch (NotSupportedException) {  }
+                       try {
+                               ginst.GetNestedType ("foo", BindingFlags.Public | BindingFlags.Instance);
+                               Assert.Fail ("#7");
+                       } catch (NotSupportedException) {  }
+                       try {
+                               ginst.GetProperty ("foo");
+                               Assert.Fail ("#8");
+                       } catch (NotSupportedException) {  }
+                       try {
+                               var x = ginst.TypeInitializer;
+                               Assert.Fail ("#9");
+                       } catch (NotSupportedException) {  }
+                       try {
+                               var x = ginst.InvokeMember ("foo", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance, null, null, null);
+                               Assert.Fail ("#10");
+                       } catch (NotSupportedException) {  }
+                       try {
+                               ginst.IsDefined (typeof (int), true);
+                               Assert.Fail ("#11");
+                       } catch (NotSupportedException) {  }
+                       try {
+                               ginst.GetCustomAttributes (true);
+                               Assert.Fail ("#12");
+                       } catch (NotSupportedException) {  }
+                       try {
+                               ginst.GetCustomAttributes (typeof (int), true);
+                               Assert.Fail ("#13");
+                       } catch (NotSupportedException) {  }
+               }
        }
 #endif
 }
index 4e3aa2fcd3cc2997f4cad6e1a8180f45ee1a54a9..035c86f380cfee9945fbc5c10ce7abb33b48952b 100644 (file)
@@ -1,3 +1,8 @@
+2009-08-13  Zoltan Varga  <vargaz@gmail.com>
+
+       * GCHandleTest.cs: Add a test for null GC handles with type 
+       WeakTrackResurrection.
+
 2009-06-20  Zoltan Varga  <vargaz@gmail.com>
 
        * *.cs: Convert all tests to new-style nunit classes/methods.
index b654f1ac18b069ef346bf6acde488a85ddd282ee..2a98aebc4fbe21dd330c80632e9450b640a876f2 100644 (file)
@@ -31,6 +31,12 @@ namespace MonoTests.System.Runtime.InteropServices
                        GCHandle gch = (GCHandle)ptr;
                }
 
+               [Test]
+               public void AllocNullWeakTrack ()
+               {
+                       GCHandle gch = GCHandle.Alloc(null, GCHandleType.WeakTrackResurrection);
+               }
+
                [Test]
                [ExpectedException (typeof (InvalidOperationException))]
                public void AddrOfPinnedObjectNormal ()
diff --git a/mcs/class/corlib/Test/System.Threading/AggregateExceptionTests.cs b/mcs/class/corlib/Test/System.Threading/AggregateExceptionTests.cs
deleted file mode 100644 (file)
index fbab269..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-#if NET_4_0
-// AggregateExceptionTests.cs
-//
-// Copyright (c) 2008 Jérémie "Garuma" Laval
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-//
-
-using System;
-using System.Linq;
-using System.Threading;
-
-using NUnit;
-using NUnit.Core;
-using NUnit.Framework;
-
-namespace ParallelFxTests
-{
-       
-       [TestFixture()]
-       public class AggregateExceptionTests
-       {
-               AggregateException e;
-               
-               [SetUpAttribute]
-               public void Setup()
-               {
-                       e = new AggregateException(new Exception("foo"), new AggregateException(new Exception("bar"), new Exception("foobar")));
-               }
-               
-               [TestAttribute]
-               public void FlattenTestCase()
-               {
-                       AggregateException ex = e.Flatten();
-                       
-                       Assert.AreEqual(3, ex.InnerExceptions.Count, "#1");
-                       Assert.AreEqual(3, ex.InnerExceptions.Where((exception) => !(exception is AggregateException)).Count(), "#2");
-               }
-       }
-}
-#endif
index 7b21c10a6ff47b0e00951ce184df1623ff2d2fea..b334d04eab6d1484e97edb2ed4fb1afe9a50f508 100644 (file)
@@ -1,3 +1,8 @@
+2009-08-11  Jérémie Laval  <jeremie.laval@gmail.com>
+
+       * ParallelTests.cs: Remove While test case.
+       * AggregateExceptionTests.cs: Moved file.
+
 2009-07-30 Jérémie Laval  <jeremie.laval@gmail.com>
 
        * System.Threading.Tasks/TaskTest.cs:
index dbea29a17c1618cb030457474cb5857bdd7de1d6..225b766cf638d23ba6351eed2cc03ab94a8566de 100644 (file)
@@ -98,6 +98,7 @@ namespace ParallelFxTests
                        Parallel.ForEach (e, delegate (int element) { throw new Exception ("foo"); });
                }
                
+               /* Disabled as this is an API addition
                [Test]
                public void ParallelWhileTestCase()
                {
@@ -110,7 +111,7 @@ namespace ParallelFxTests
                                Assert.Greater(i, 10, "#1");
                                Assert.AreEqual(10, count, "#2");
                        });
-               }
+               }*/
        }
 }
 #endif
diff --git a/mcs/class/corlib/Test/System/AggregateExceptionTests.cs b/mcs/class/corlib/Test/System/AggregateExceptionTests.cs
new file mode 100644 (file)
index 0000000..fbab269
--- /dev/null
@@ -0,0 +1,58 @@
+#if NET_4_0
+// AggregateExceptionTests.cs
+//
+// Copyright (c) 2008 Jérémie "Garuma" Laval
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+//
+
+using System;
+using System.Linq;
+using System.Threading;
+
+using NUnit;
+using NUnit.Core;
+using NUnit.Framework;
+
+namespace ParallelFxTests
+{
+       
+       [TestFixture()]
+       public class AggregateExceptionTests
+       {
+               AggregateException e;
+               
+               [SetUpAttribute]
+               public void Setup()
+               {
+                       e = new AggregateException(new Exception("foo"), new AggregateException(new Exception("bar"), new Exception("foobar")));
+               }
+               
+               [TestAttribute]
+               public void FlattenTestCase()
+               {
+                       AggregateException ex = e.Flatten();
+                       
+                       Assert.AreEqual(3, ex.InnerExceptions.Count, "#1");
+                       Assert.AreEqual(3, ex.InnerExceptions.Where((exception) => !(exception is AggregateException)).Count(), "#2");
+               }
+       }
+}
+#endif
index 01d00ecefe602a656743806639971ff4133bbf55..a4e17f9b55229950d91dfc7504af343022d75a85 100644 (file)
@@ -1492,7 +1492,6 @@ System.Threading.Tasks/Future.cs
 System.Threading.Tasks/Task.cs
 System.Threading.Tasks/TaskCompletionSource.cs
 System.Threading.Tasks/TaskSchedulerException.cs
-System.Collections.Concurrent/BlockingCollection.cs
 System.Collections.Concurrent/OrderablePartitioner.cs
 System.Collections.Concurrent/ConcurrentDictionary.cs
 System.Collections.Concurrent/Partitioner.cs
@@ -1511,10 +1510,8 @@ System.Threading/CancellationTokenSource.cs
 System.Threading/Snzi.cs
 System.Threading/CancellationToken.cs
 System.Threading/ICancelableOperation.cs
-System.Threading/Barrier.cs
 System.Threading/ParallelLoopResult.cs
 System.Threading/CSnzi.cs
-System.Threading/AggregateException.cs
 System.Threading/SpinWait.cs
 System.Threading/SemaphoreSlim.cs
 System.Threading/CancellationTokenRegistration.cs
@@ -1524,3 +1521,4 @@ System.Threading/AtomicBoolean.cs
 System.Threading/ManualResetEventSlim.cs
 System.Threading/ThreadLocal.cs
 System.Threading/Watch.cs
+System/AggregateException.cs
index 377c01c13e5e904825c33d7b934d0ddf69bdef53..0855e5a742ab588d885e64c515b1f4c11eb89bec 100644 (file)
@@ -425,7 +425,6 @@ System.Collections.Concurrent/ConcurrentSkipListTests.cs
 System.Collections.Concurrent/ConcurrentQueueTests.cs
 System.Collections.Concurrent/ConcurrentBagTests.cs
 System.Collections.Concurrent/ConcurrentStackTests.cs
-System.Collections.Concurrent/BlockingCollectionTests.cs
 System.Collections.Concurrent/ConcurrentDictionaryTests.cs
 System.Collections.Concurrent/CollectionStressTestHelper.cs
 System.Collections.Concurrent/ParallelConcurrentQueueTests.cs
@@ -434,6 +433,6 @@ System.Threading/ManualResetEventSlimTests.cs
 System.Threading/SemaphoreSlimTests.cs
 System.Threading/ParallelTests.cs
 System.Threading/CountdownEventTests.cs
-System.Threading/AggregateExceptionTests.cs
+System/AggregateExceptionTests.cs
 System.Threading/ThreadLazyTests.cs
 System.Threading/ParallelTestHelper.cs
diff --git a/mcs/errors/cs0026-3.cs b/mcs/errors/cs0026-3.cs
deleted file mode 100644 (file)
index b0ec7ea..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-// CS0026: Keyword `this' is not valid in a static property, static method, or static field initializer
-// Line: 7
-
-class A : B
-{
-       public A () 
-               : base (this)
-       {
-       }
-}
-
-class B
-{
-       public B (B b)
-       {
-       }
-}
\ No newline at end of file
diff --git a/mcs/errors/cs0027-3.cs b/mcs/errors/cs0027-3.cs
new file mode 100644 (file)
index 0000000..cbe891c
--- /dev/null
@@ -0,0 +1,18 @@
+// CS0007: Keyword `this' is not available in the current context
+// Line: 14
+
+class B
+{
+       public B (object o)
+       {
+       }
+}
+
+class C : B
+{
+       public C ()
+               : base (this)
+       {
+       }
+}
+
diff --git a/mcs/errors/cs0027-4.cs b/mcs/errors/cs0027-4.cs
new file mode 100644 (file)
index 0000000..cae5dc9
--- /dev/null
@@ -0,0 +1,7 @@
+// CS0027: Keyword `this' is not available in the current context
+// Line: 6
+
+class Program
+{
+       const object y = this;
+}
diff --git a/mcs/errors/cs0120-14.cs b/mcs/errors/cs0120-14.cs
new file mode 100644 (file)
index 0000000..9066b84
--- /dev/null
@@ -0,0 +1,20 @@
+// CS0120: An object reference is required to access non-static member `C.i'
+// Line: 16
+
+class B
+{
+       public B (object o)
+       {
+       }
+}
+
+class C : B
+{
+       int i;
+       
+       public C ()
+               : base (i)
+       {
+       }
+}
+
diff --git a/mcs/errors/cs0120-15.cs b/mcs/errors/cs0120-15.cs
new file mode 100644 (file)
index 0000000..d89b17a
--- /dev/null
@@ -0,0 +1,25 @@
+// CS0120: An object reference is required to access non-static member `C.Enum()'
+// Line: 20
+
+using System;
+
+enum Enum
+{
+       Test
+}
+
+class A : Attribute
+{
+       public A (object e)
+       {
+       }
+}
+
+class C
+{
+       [A (Enum.Test)]
+       int Enum ()
+       {
+               return 0;
+       }
+}
diff --git a/mcs/errors/cs0206-2.cs b/mcs/errors/cs0206-2.cs
new file mode 100644 (file)
index 0000000..2105906
--- /dev/null
@@ -0,0 +1,27 @@
+// CS0206: A property or indexer may not be passed as an out or ref parameter
+// Line: 22
+
+using System;
+
+namespace N
+{
+       public class Test
+       {
+               public double this[int i]
+               {
+                       get { return 1; }
+               }
+
+               public static void WriteOutData(out double d)
+               {
+                       d = 5.0;
+               }
+
+               public static void Main(string[] args)
+               {
+                       Test test = new Test();
+                       WriteOutData(out test[1]);
+               }
+       }
+}
+
diff --git a/mcs/errors/cs0432-3.cs b/mcs/errors/cs0432-3.cs
new file mode 100644 (file)
index 0000000..492aac1
--- /dev/null
@@ -0,0 +1,6 @@
+// CS0432: Alias `Sa' not found
+// Line: 6
+
+using S = System;
+
+[assembly: Sa::CLSCompliantAttribute (false)]
diff --git a/mcs/errors/cs0533-4.cs b/mcs/errors/cs0533-4.cs
new file mode 100644 (file)
index 0000000..4d2eee8
--- /dev/null
@@ -0,0 +1,12 @@
+// CS0533: `B.MyEvent' hides inherited abstract member `A.MyEvent'
+// Line: 11
+
+using System;
+
+abstract class A {
+       public abstract event EventHandler MyEvent;
+}
+
+class B : A {
+       public event EventHandler MyEvent;
+}
diff --git a/mcs/errors/cs0534-5.cs b/mcs/errors/cs0534-5.cs
deleted file mode 100644 (file)
index 66b2a27..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-// CS0534: `B' does not implement inherited abstract member `A.MyEvent.add'
-// Line: 11
-
-using System;
-
-abstract class A {
-       public abstract event EventHandler MyEvent;
-}
-
-class B : A {
-       public event EventHandler MyEvent;
-}
diff --git a/mcs/errors/cs1967.cs b/mcs/errors/cs1967.cs
new file mode 100644 (file)
index 0000000..696c979
--- /dev/null
@@ -0,0 +1,6 @@
+// CS1967: A constraint cannot be the dynamic type
+// Line: 4
+
+class C<T> where T : dynamic
+{
+}
index 3e04f6424366bc689bcecba600b340cb18edc16c..eadb8ab4eac1bb08cf26575f5996f2fca3dd6241 100644 (file)
@@ -1,3 +1,72 @@
+2009-08-19  Marek Safar  <marek.safar@gmail.com>
+
+       * generic.cs, iterators.cs, expression.cs, statement.cs, ecore.cs,
+       cs-parser.jay, attribute.cs, codegen.cs: Better error reports.
+
+2009-08-18  Marek Safar  <marek.safar@gmail.com>
+
+       * *.cs: Removed boolean fields from EmitContext.
+
+2009-08-18  Marek Safar  <marek.safar@gmail.com>
+
+       * *.cs: Add IResolveContext::IsStatic.
+
+2009-08-18  Marek Safar  <marek.safar@gmail.com>
+
+       * *.cs: Moved TopBlock's methods from EmitContext to TopBlock.
+
+2009-08-17  Marek Safar  <marek.safar@gmail.com>
+
+       * *.cs: Removed DeclContainer from EmitContext.
+
+2009-08-17  Marek Safar  <marek.safar@gmail.com>
+
+       * *.cs: Add IResolveContext::CurrentTypeParameters.
+
+2009-08-14  Marek Safar  <marek.safar@gmail.com>
+
+       * *.cs: Removed TypeContainer and ContainerType from EmitContext.
+
+2009-08-14  Marek Safar  <marek.safar@gmail.com>
+
+       * decl.cs, expression.cs, namespace.cs, ecore.cs, class.cs,
+       codegen.cs: Add IResolveContext::LookupExtensionMethod.
+
+2009-08-13  Marek Safar  <marek.safar@gmail.com>
+
+       * decl.cs: Look in PartialContainer for parent type parameters.
+
+2009-08-13  Marek Safar  <marek.safar@gmail.com>
+
+       * decl.cs, namespace.cs, ecore.cs, class.cs, attribute.cs,
+       codegen.cs: Add IResolveContext::LookupTypeParameter.
+
+2009-08-13  Marek Safar  <marek.safar@gmail.com>
+
+       * lambda.cs, expression.cs, statement.cs, namespace.cs, ecore.cs:
+       Moved resolved logic from Emit to Resolve.
+
+2009-08-13  Marek Safar  <marek.safar@gmail.com>
+
+       * parameter.cs, decl.cs, roottypes.cs, class.cs, attribute.cs,
+       codegen.cs: Reworked atttributes handling of ResolveContext.
+
+2009-08-12  Marek Safar  <marek.safar@gmail.com>
+
+       * decl.cs, ecore.cs, class.cs, attribute.cs, codegen.cs: Pushed
+       LookupNamespaceOrType to ResolveContext.
+
+2009-08-12  Marek Safar  <marek.safar@gmail.com>
+
+       * typemanager.cs, decl.cs, expression.cs, namespace.cs, ecore.cs,
+       class.cs: Removed unused parameters and methods.
+
+2009-08-11  Marek Safar  <marek.safar@gmail.com>
+
+       * generic.cs, lambda.cs, anonymous.cs, statement.cs, generic-mcs.cs,
+       codegen.cs: Finding the best common type of a set of expressions for
+       lambda statements.
+
 2009-08-07  Marek Safar  <marek.safar@gmail.com>
 
        * dynamic.cs, expression.cs: More dynamic conversions.
index db407ac94a44e01e6a57feed8a09c6e564672e52..61ae9f270150aa001c57fa88f3ba80e816c4199e 100644 (file)
@@ -150,7 +150,7 @@ namespace Mono.CSharp {
                // Local variable which holds this storey instance
                public LocalTemporary Instance;
 
-               public AnonymousMethodStorey (Block block, DeclSpace parent, MemberBase host, GenericMethod generic, string name)
+               public AnonymousMethodStorey (Block block, TypeContainer parent, MemberBase host, GenericMethod generic, string name)
                        : base (parent, generic, MakeMemberName (host, name, generic, block.StartLocation), Modifiers.PRIVATE)
                {
                        Parent = parent;
@@ -174,7 +174,7 @@ namespace Mono.CSharp {
 
                public void AddCapturedThisField (EmitContext ec)
                {
-                       TypeExpr type_expr = new TypeExpression (ec.ContainerType, Location);
+                       TypeExpr type_expr = new TypeExpression (ec.CurrentType, Location);
                        Field f = AddCompilerGeneratedField ("<>f__this", type_expr);
                        f.Define ();
                        hoisted_this = new HoistedThis (this, f);
@@ -299,7 +299,7 @@ namespace Mono.CSharp {
                                TypeArguments targs = new TypeArguments ();
 
                                if (tparams.Length < CountTypeParameters) {
-                                       TypeParameter[] parent_tparams = ec.DeclContainer.Parent.PartialContainer.TypeParameters;
+                                       TypeParameter[] parent_tparams = ec.GenericDeclContainer.Parent.PartialContainer.TypeParameters;
                                        for (int i = 0; i < parent_tparams.Length; ++i)
                                                targs.Add (new TypeParameterExpr (parent_tparams[i], Location));
                                }
@@ -403,7 +403,7 @@ namespace Mono.CSharp {
                public AnonymousMethodStorey GetGenericStorey ()
                {
                        DeclSpace storey = this;
-                       while (storey != null && storey.CurrentTypeParameters.Length == 0)
+                       while (storey != null && storey.CurrentTypeParameters == null)
                                storey = storey.Parent;
 
                        return storey as AnonymousMethodStorey;
@@ -600,10 +600,10 @@ namespace Mono.CSharp {
                //
                public Type MutateGenericArgument (Type type)
                {
-                       foreach (TypeParameter tp in CurrentTypeParameters) {
-                               if (tp.Name == type.Name) {
+                       if (CurrentTypeParameters != null) {
+                               TypeParameter tp = TypeParameter.FindTypeParameter (CurrentTypeParameters, type.Name);
+                               if (tp != null)
                                        return tp.Type;
-                               }
                        }
 
                        return type;
@@ -873,8 +873,8 @@ namespace Mono.CSharp {
                //
                public bool ImplicitStandardConversionExists (EmitContext ec, Type delegate_type)
                {
-                       using (ec.With (EmitContext.Flags.InferReturnType, false)) {
-                               using (ec.Set (EmitContext.Flags.ProbingMode)) {
+                       using (ec.With (EmitContext.Options.InferReturnType, false)) {
+                               using (ec.Set (EmitContext.Options.ProbingMode)) {
                                        return Compatible (ec, delegate_type) != null;
                                }
                        }
@@ -1007,17 +1007,13 @@ namespace Mono.CSharp {
                public Type InferReturnType (EmitContext ec, TypeInferenceContext tic, Type delegate_type)
                {
                        AnonymousMethodBody am;
-                       using (ec.Set (EmitContext.Flags.ProbingMode | EmitContext.Flags.InferReturnType)) {
-                               am = CompatibleMethod (ec, tic, TypeManager.null_type, delegate_type);
+                       using (ec.Set (EmitContext.Options.ProbingMode | EmitContext.Options.InferReturnType)) {
+                               am = CompatibleMethod (ec, tic, InternalType.Arglist, delegate_type);
                        }
                        
                        if (am == null)
                                return null;
 
-                       // Stop referencing gmcs NullLiteral type
-                       if (am.ReturnType == TypeManager.null_type)
-                               am.ReturnType = null;
-
                        return am.ReturnType;
                }
 
@@ -1041,7 +1037,7 @@ namespace Mono.CSharp {
                        //
 
                        MethodInfo invoke_mb = Delegate.GetInvokeMethod (
-                               ec.ContainerType, delegate_type);
+                               ec.CurrentType, delegate_type);
                        Type return_type = TypeManager.TypeToCoreType (invoke_mb.ReturnType);
 
 #if MS_COMPATIBLE
@@ -1122,7 +1118,7 @@ namespace Mono.CSharp {
 
                public override Expression DoResolve (EmitContext ec)
                {
-                       if (!ec.IsAnonymousMethodAllowed) {
+                       if (ec.HasSet (EmitContext.Options.ConstantScope)) {
                                Report.Error (1706, loc, "Anonymous methods and lambda expressions cannot be used in the current context");
                                return null;
                        }
@@ -1223,11 +1219,11 @@ namespace Mono.CSharp {
                                Block = am.Block;
                        }
 
-                       public override EmitContext CreateEmitContext (DeclSpace tc, ILGenerator ig)
+                       public override EmitContext CreateEmitContext (ILGenerator ig)
                        {
                                EmitContext aec = AnonymousMethod.aec;
                                aec.ig = ig;
-                               aec.IsStatic = (ModFlags & Modifiers.STATIC) != 0;
+                               aec.AnonymousStatic = (ModFlags & Modifiers.STATIC) != 0;
                                return aec;
                        }
 
@@ -1302,36 +1298,37 @@ namespace Mono.CSharp {
                {
                        // TODO: Implement clone
                        aec = new EmitContext (
-                               ec.ResolveContext, ec.TypeContainer, ec.DeclContainer,
-                               Location, null, ReturnType,
-                               (ec.InUnsafe ? Modifiers.UNSAFE : 0), /* No constructor */ false);
+                               ec.ResolveContext, ec.GenericDeclContainer,
+                               null, ReturnType);
 
                        aec.CurrentAnonymousMethod = this;
-                       aec.IsStatic = ec.IsStatic;
 
                        IDisposable aec_dispose = null;
-                       EmitContext.Flags flags = 0;
-                       if (ec.InferReturnType)
-                               flags |= EmitContext.Flags.InferReturnType;
+                       EmitContext.Options flags = 0;
+                       if (ec.HasSet (EmitContext.Options.InferReturnType)) {
+                               flags |= EmitContext.Options.InferReturnType;
+                               aec.ReturnTypeInference = new TypeInferenceContext ();
+                       }
 
                        if (ec.IsInProbingMode)
-                               flags |= EmitContext.Flags.ProbingMode;
+                               flags |= EmitContext.Options.ProbingMode;
 
-                       if (ec.IsInFieldInitializer)
-                               flags |= EmitContext.Flags.InFieldInitializer;
+                       if (ec.HasSet (EmitContext.Options.FieldInitializerScope))
+                               flags |= EmitContext.Options.FieldInitializerScope;
 
-                       if (ec.IsInUnsafeScope)
-                               flags |= EmitContext.Flags.InUnsafe;
+                       if (ec.InUnsafe)
+                               flags |= EmitContext.Options.UnsafeScope;
 
                        // HACK: Flag with 0 cannot be set 
                        if (flags != 0)
                                aec_dispose = aec.Set (flags);
 
-                       bool unreachable;
-                       bool res = aec.ResolveTopBlock (ec, Block, Block.Parameters, null, out unreachable);
+                       bool res = Block.Resolve (ec.CurrentBranching, aec, Block.Parameters, null);
 
-                       if (ec.InferReturnType)
-                               ReturnType = aec.ReturnType;
+                       if (ec.HasSet (EmitContext.Options.InferReturnType)) {
+                               aec.ReturnTypeInference.FixAllTypes ();
+                               ReturnType = aec.ReturnTypeInference.InferredTypeArguments [0];
+                       }
 
                        if (aec_dispose != null) {
                                aec_dispose.Dispose ();
@@ -1424,7 +1421,7 @@ namespace Mono.CSharp {
                                modifiers = Modifiers.STATIC | Modifiers.PRIVATE;
                        }
 
-                       DeclSpace parent = storey != null ? storey : ec.TypeContainer;
+                       TypeContainer parent = storey != null ? storey : ec.CurrentTypeDefinition;
 
                        MemberCore mc = ec.ResolveContext as MemberCore;
                        string name = CompilerGeneratedClass.MakeName (parent != storey ? mc.Name : null,
@@ -1439,7 +1436,7 @@ namespace Mono.CSharp {
                                        new TypeExpression (ReturnType, Location), parameters);
 
                                ArrayList list = new ArrayList ();
-                               foreach (TypeParameter tparam in ((IMethodData)mc).GenericMethod.CurrentTypeParameters) {
+                               foreach (TypeParameter tparam in ec.CurrentTypeParameters) {
                                        if (tparam.Constraints != null)
                                                list.Add (tparam.Constraints.Clone ());
                                }
@@ -1564,7 +1561,7 @@ namespace Mono.CSharp {
 
                        ig.Emit (OpCodes.Ldftn, delegate_method);
 
-                       ConstructorInfo constructor_method = Delegate.GetConstructor (ec.ContainerType, type);
+                       ConstructorInfo constructor_method = Delegate.GetConstructor (ec.CurrentType, type);
 #if MS_COMPATIBLE
             if (type.IsGenericType && type is TypeBuilder)
                 constructor_method = TypeBuilder.GetConstructor (type, constructor_method);
index f86002f64440de2194d020c47189f45b5f6c8a78..39dffc82ad2f9842fe8c29cc771ec036b49d41a9 100644 (file)
@@ -109,7 +109,7 @@ namespace Mono.CSharp
                        if (Expr == EmptyExpression.Null)
                                return;
 
-                       using (ec.With (EmitContext.Flags.DoFlowAnalysis, true)) {
+                       using (ec.With (EmitContext.Options.DoFlowAnalysis, true)) {
                                // Verify that the argument is readable
                                if (ArgType != AType.Out)
                                        Expr = Expr.Resolve (ec);
index 8be80e55a9fec7178c889b2a2162124eebdc2410..c830be76d489af2f1123d3d6fe9758bf4f2d4df4 100644 (file)
@@ -358,10 +358,7 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-                       if ((source.eclass == ExprClass.Type) && (source is TypeExpr)) {
-                               source.Error_UnexpectedKind (ec.DeclContainer, "variable or value", loc);
-                               return null;
-                       } else if ((RootContext.Version == LanguageVersion.ISO_1) &&
+                       if ((RootContext.Version == LanguageVersion.ISO_1) &&
                                   (source is MethodGroupExpr)){
                                ((MethodGroupExpr) source).ReportUsageError ();
                                return null;
@@ -489,17 +486,16 @@ namespace Mono.CSharp {
                                //
 
                                // TODO: Use ResolveContext only
-                               EmitContext f_ec = new EmitContext (rc, rc.DeclContainer, loc, null, TypeManager.void_type, 0, true);
-                               f_ec.IsStatic = ec.IsStatic;
+                               EmitContext f_ec = new EmitContext (rc, rc.GenericDeclContainer, null, TypeManager.void_type);
                                f_ec.CurrentBlock = ec.CurrentBlock;
 
-                               EmitContext.Flags flags = EmitContext.Flags.InFieldInitializer;
-                               if (ec.IsInUnsafeScope)
-                                       flags |= EmitContext.Flags.InUnsafe;
-
-                               f_ec.Set (flags);
+                               EmitContext.Options flags = EmitContext.Options.FieldInitializerScope | EmitContext.Options.ConstructorScope;
+                               if (ec.InUnsafe)
+                                       flags |= EmitContext.Options.UnsafeScope;
 
-                               resolved = base.DoResolve (f_ec) as ExpressionStatement;
+                               using (f_ec.Set (flags)) {
+                                       resolved = base.DoResolve (f_ec) as ExpressionStatement;
+                               }
                        }
 
                        return resolved;
@@ -632,7 +628,7 @@ namespace Mono.CSharp {
                                return null;
 
                        MemberAccess ma = target as MemberAccess;
-                       using (ec.Set (EmitContext.Flags.InCompoundAssignment)) {
+                       using (ec.Set (EmitContext.Options.CompoundAssignmentScope)) {
                                target = target.Resolve (ec);
                        }
                        
index 8fb575e3a9462b75efdca6f5a361228c3bf0f5e0..fd6475fbdfae11083cf5ce109cbb6652cb348319 100644 (file)
@@ -29,28 +29,30 @@ namespace Mono.CSharp {
        ///   Base class for objects that can have Attributes applied to them.
        /// </summary>
        public abstract class Attributable {
-               /// <summary>
-               ///   Attributes for this type
-               /// </summary>
+               //
+               // Holds all attributes attached to this element
+               //
                protected Attributes attributes;
 
-               public Attributable (Attributes attrs)
+               public void AddAttributes (Attributes attrs, IResolveContext context)
                {
-                       if (attrs != null)
-                               OptAttributes = attrs;
+                       if (attrs == null)
+                               return;
+
+                       if (attributes == null)
+                               attributes = attrs;
+                       else
+                               throw new NotImplementedException ();
+
+                       attributes.AttachTo (this, context);
                }
 
-               public Attributes OptAttributes 
-               {
+               public Attributes OptAttributes {
                        get {
                                return attributes;
                        }
                        set {
                                attributes = value;
-
-                               if (attributes != null) {
-                                       attributes.AttachTo (this);
-                               }
                        }
                }
 
@@ -64,8 +66,6 @@ namespace Mono.CSharp {
                /// </summary>
                public abstract AttributeTargets AttributeTargets { get; }
 
-               public abstract IResolveContext ResolveContext { get; }
-
                public abstract bool IsClsComplianceRequired ();
 
                /// <summary>
@@ -77,53 +77,9 @@ namespace Mono.CSharp {
 
        public class Attribute : Expression
        {
-               //
-               // Wraps owner resolve context, the owner is an attribute
-               // parent and the rest is exactly same
-               //
-               struct AttributeResolveContext : IResolveContext
-               {
-                       readonly IResolveContext rc;
-
-                       public AttributeResolveContext (IResolveContext rc)
-                       {
-                               this.rc = rc;
-                       }
-
-                       #region IResolveContext Members
-
-                       public DeclSpace DeclContainer {
-                               get {
-                                       DeclSpace ds = rc as DeclSpace;
-                                       if (ds == null)
-                                               return rc.DeclContainer;
-
-                                       return ds;
-                               }
-                       }
-
-                       public bool IsInObsoleteScope {
-                               get { return rc.IsInObsoleteScope; }
-                       }
-
-                       public bool IsInUnsafeScope {
-                               get { return rc.IsInUnsafeScope; }
-                       }
-
-                       public DeclSpace GenericDeclContainer {
-                               get { return rc.GenericDeclContainer; }
-                       }
-
-                       #endregion
-               }
-
                public readonly string ExplicitTarget;
                public AttributeTargets Target;
-
-               // TODO: remove this member
-               public readonly string    Name;
-               public readonly Expression LeftExpr;
-               public readonly string Identifier;
+               readonly ATypeNameExpression expression;
 
                Arguments PosArguments;
                Arguments NamedArguments;
@@ -131,8 +87,16 @@ namespace Mono.CSharp {
                bool resolve_error;
                readonly bool nameEscaped;
 
-               // It can contain more onwers when the attribute is applied to multiple fiels.
-               protected Attributable[] owners;
+               //
+               // An attribute can be attached to multiple targets (e.g. multiple fields)
+               //
+               protected Attributable[] targets;
+
+               //
+               // A member context for the attribute, it's much easier to hold it here
+               // than trying to pull it during resolve
+               //
+               IResolveContext context;
 
                static readonly AttributeUsageAttribute DefaultUsageAttribute = new AttributeUsageAttribute (AttributeTargets.All);
                static Assembly orig_sec_assembly;
@@ -149,11 +113,13 @@ namespace Mono.CSharp {
                // Cache for parameter-less attributes
                static PtrHashtable att_cache;
 
-               public Attribute (string target, Expression left_expr, string identifier, Arguments[] args, Location loc, bool nameEscaped)
+               public Attribute (string target, ATypeNameExpression expr, Arguments[] args, Location loc, bool nameEscaped)
                {
-                       LeftExpr = left_expr;
-                       Identifier = identifier;
-                       Name = LeftExpr == null ? identifier : LeftExpr + "." + identifier;
+                       //LeftExpr = left_expr;
+                       //Identifier = identifier;
+                       //Name = LeftExpr == null ? identifier : LeftExpr + "." + identifier;
+
+                       this.expression = expr;
                        if (args != null) {
                                PosArguments = args [0];
                                NamedArguments = args [1];                              
@@ -165,7 +131,7 @@ namespace Mono.CSharp {
 
                public Attribute Clone ()
                {
-                       Attribute a = new Attribute (ExplicitTarget, LeftExpr, Identifier, null, loc, nameEscaped);
+                       Attribute a = new Attribute (ExplicitTarget, expression, null, loc, nameEscaped);
                        a.PosArguments = PosArguments;
                        a.NamedArguments = NamedArguments;
                        return a;
@@ -182,22 +148,30 @@ namespace Mono.CSharp {
                        att_cache = new PtrHashtable ();
                }
 
-               public virtual void AttachTo (Attributable owner)
+               //
+               // When the same attribute is attached to multiple fiels
+               // we use @target field as a list of targets. The attribute
+               // has to be resolved only once but emitted for each target.
+               //
+               public virtual void AttachTo (Attributable target, IResolveContext context)
                {
-                       if (this.owners == null) {
-                               this.owners = new Attributable[1] { owner };
+                       if (this.targets == null) {
+                               this.targets = new Attributable[] { target };
+                               this.context = context;
                                return;
                        }
 
-                       // When the same attribute is attached to multiple fiels
-                       // we use this extra_owners as a list of owners. The attribute
-                       // then can be removed because will be emitted when first owner
-                       // is served
-                       Attributable[] new_array = new Attributable [this.owners.Length + 1];
-                       owners.CopyTo (new_array, 0);
-                       new_array [owners.Length] = owner;
-                       this.owners = new_array;
-                       owner.OptAttributes = null;
+                       // Resize target array
+                       Attributable[] new_array = new Attributable [this.targets.Length + 1];
+                       targets.CopyTo (new_array, 0);
+                       new_array [targets.Length] = target;
+                       this.targets = new_array;
+
+                       // No need to update context, different targets cannot have
+                       // different contexts, it's enough to remove same attributes
+                       // from secondary members.
+
+                       target.OptAttributes = null;
                }
 
                void Error_InvalidNamedArgument (NamedArgument name)
@@ -222,12 +196,6 @@ namespace Mono.CSharp {
                                      "expression or array creation expression");
                }
                
-               static void Error_TypeParameterInAttribute (Location loc)
-               {
-                       Report.Error (
-                               -202, loc, "Can not use a type parameter in an attribute");
-               }
-
                public void Error_MissingGuidAttribute ()
                {
                        Report.Error (596, Location, "The Guid attribute must be specified with the ComImport attribute");
@@ -255,33 +223,25 @@ namespace Mono.CSharp {
 
                Attributable Owner {
                        get {
-                               return owners [0];
+                               return targets [0];
                        }
                }
 
-               protected virtual TypeExpr ResolveAsTypeTerminal (Expression expr, IResolveContext ec, bool silent)
+               protected virtual TypeExpr ResolveAsTypeTerminal (Expression expr, IResolveContext ec)
                {
-                       return expr.ResolveAsTypeTerminal (ec, silent);
+                       return expr.ResolveAsTypeTerminal (ec, false);
                }
 
-               Type ResolvePossibleAttributeType (string name, bool silent, ref bool is_attr)
+               Type ResolvePossibleAttributeType (ATypeNameExpression expr, ref bool is_attr)
                {
-                       IResolveContext rc = new AttributeResolveContext (Owner.ResolveContext);
-
-                       TypeExpr te;
-                       if (LeftExpr == null) {
-                               te = ResolveAsTypeTerminal (new SimpleName (name, Location), rc, silent);
-                       } else {
-                               te = ResolveAsTypeTerminal (new MemberAccess (LeftExpr, name), rc, silent);
-                       }
-
+                       TypeExpr te = ResolveAsTypeTerminal (expr, context);
                        if (te == null)
                                return null;
 
                        Type t = te.Type;
                        if (TypeManager.IsSubclassOf (t, TypeManager.attribute_type)) {
                                is_attr = true;
-                       } else if (!silent) {
+                       } else {
                                Report.SymbolRelatedToPreviousError (t);
                                Report.Error (616, Location, "`{0}': is not an attribute class", TypeManager.CSharpName (t));
                        }
@@ -293,16 +253,33 @@ namespace Mono.CSharp {
                /// </summary>
                void ResolveAttributeType ()
                {
+                       Report.IMessageRecorder msg_recorder = new Report.MessageRecorder ();
+                       Report.IMessageRecorder prev_recorder = Report.SetMessageRecorder (msg_recorder);
+                       int errors = Report.Errors;
+
                        bool t1_is_attr = false;
-                       Type t1 = ResolvePossibleAttributeType (Identifier, true, ref t1_is_attr);
+                       Type t1 = ResolvePossibleAttributeType (expression, ref t1_is_attr);
 
                        bool t2_is_attr = false;
-                       Type t2 = nameEscaped ? null :
-                               ResolvePossibleAttributeType (Identifier + "Attribute", true, ref t2_is_attr);
+                       Type t2;
+                       ATypeNameExpression expanded = null;
+
+                       if (nameEscaped) {
+                               t2 = null;
+                       } else {
+                               expanded = (ATypeNameExpression) expression.Clone (null);
+                               expanded.Name += "Attribute";
+
+                               t2 = ResolvePossibleAttributeType (expanded, ref t2_is_attr);
+                       }
+
+                       msg_recorder.EndSession ();
+                       Report.SetMessageRecorder (prev_recorder);
+                       Report.Errors = errors;
 
                        if (t1_is_attr && t2_is_attr) {
-                               Report.Error (1614, Location, "`{0}' is ambiguous between `{0}' and `{0}Attribute'. " +
-                                             "Use either `@{0}' or `{0}Attribute'", GetSignatureForError ());
+                               Report.Error (1614, Location, "`{0}' is ambiguous between `{1}' and `{2}'. Use either `@{0}' or `{0}Attribute'",
+                                       GetSignatureForError (), expression.GetSignatureForError (), expanded.GetSignatureForError ());
                                resolve_error = true;
                                return;
                        }
@@ -317,13 +294,7 @@ namespace Mono.CSharp {
                                return;
                        }
 
-                       if (t1 == null && t2 == null)
-                               ResolvePossibleAttributeType (Identifier, false, ref t1_is_attr);
-                       if (t1 != null)
-                               ResolvePossibleAttributeType (Identifier, false, ref t1_is_attr);
-                       if (t2 != null)
-                               ResolvePossibleAttributeType (Identifier + "Attribute", false, ref t2_is_attr);
-
+                       msg_recorder.PrintMessages ();
                        resolve_error = true;
                }
 
@@ -339,7 +310,7 @@ namespace Mono.CSharp {
                        if (Type != null)
                                return TypeManager.CSharpName (Type);
 
-                       return LeftExpr == null ? Identifier : LeftExpr.GetSignatureForError () + "." + Identifier;
+                       return expression.GetSignatureForError ();
                }
 
                public bool HasSecurityAttribute {
@@ -366,6 +337,11 @@ namespace Mono.CSharp {
                                t == TypeManager.type_type;
                }
 
+               // TODO: Don't use this ambiguous value
+               public string Name {
+                       get { return expression.Name; }
+               }
+
                void ApplyModuleCharSet ()
                {
                        if (Type != PredefinedAttributes.Get.DllImport)
@@ -419,14 +395,10 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       Attributable owner = Owner;
-                       DeclSpace ds = owner.ResolveContext as DeclSpace;
-                       if (ds == null)
-                               ds = owner.ResolveContext.DeclContainer;
-                       
-                       EmitContext ec = new EmitContext (owner.ResolveContext, ds, ds,
-                               Location, null, typeof (Attribute), ds.ModFlags, false);
-                       ec.IsAnonymousMethodAllowed = false;
+                       DeclSpace ds = context.GenericDeclContainer;
+                       EmitContext ec = new EmitContext (context, ds,
+                               null, typeof (Attribute));
+                       ec.Set (EmitContext.Options.ConstantScope);
 
                        ConstructorInfo ctor = ResolveConstructor (ec);
                        if (ctor == null) {
@@ -482,7 +454,7 @@ namespace Mono.CSharp {
                                        throw new NotImplementedException ("dynamic");
                        }
 
-                       MethodGroupExpr mg = MemberLookupFinal (ec, ec.ContainerType,
+                       MethodGroupExpr mg = MemberLookupFinal (ec, ec.CurrentType,
                                Type, ConstructorInfo.ConstructorName, MemberTypes.Constructor,
                                BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
                                Location) as MethodGroupExpr;
@@ -565,13 +537,13 @@ namespace Mono.CSharp {
                                a.Resolve (ec);
 
                                Expression member = Expression.MemberLookup (
-                                       ec.ContainerType, Type, name,
+                                       ec.CurrentType, Type, name,
                                        MemberTypes.All,
                                        BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static,
                                        Location);
 
                                if (member == null) {
-                                       member = Expression.MemberLookup (ec.ContainerType, Type, name,
+                                       member = Expression.MemberLookup (ec.CurrentType, Type, name,
                                                MemberTypes.All, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static,
                                                Location);
 
@@ -592,11 +564,6 @@ namespace Mono.CSharp {
                                        return false;
                                }
 
-                               if (a.Expr is TypeParameterExpr){
-                                       Error_TypeParameterInAttribute (Location);
-                                       return false;
-                               }
-
                                ObsoleteAttribute obsolete_attr;
 
                                if (member is PropertyExpr) {
@@ -655,7 +622,7 @@ namespace Mono.CSharp {
                                        field_infos.Add (fi);
                                }
 
-                               if (obsolete_attr != null && !Owner.ResolveContext.IsInObsoleteScope)
+                               if (obsolete_attr != null && !context.IsInObsoleteScope)
                                        AttributeTester.Report_ObsoleteMessage (obsolete_attr, member.GetSignatureForError (), member.Location);
                        }
 
@@ -1237,10 +1204,9 @@ namespace Mono.CSharp {
                        }
 
                        try {
-                               foreach (Attributable owner in owners)
-                                       owner.ApplyAttributeBuilder (this, cb, PredefinedAttributes.Get);
-                       }
-                       catch (Exception e) {
+                               foreach (Attributable target in targets)
+                                       target.ApplyAttributeBuilder (this, cb, PredefinedAttributes.Get);
+                       } catch (Exception e) {
                                Error_AttributeEmitError (e.Message);
                                return;
                        }
@@ -1330,24 +1296,25 @@ namespace Mono.CSharp {
        {
                public readonly NamespaceEntry ns;
 
-               public GlobalAttribute (NamespaceEntry ns, string target, 
-                                       Expression left_expr, string identifier, Arguments[] args, Location loc, bool nameEscaped):
-                       base (target, left_expr, identifier, args, loc, nameEscaped)
+               public GlobalAttribute (NamespaceEntry ns, string target, ATypeNameExpression expression,
+                                       Arguments[] args, Location loc, bool nameEscaped):
+                       base (target, expression, args, loc, nameEscaped)
                {
                        this.ns = ns;
-                       this.owners = new Attributable[1];
                }
                
-               public override void AttachTo (Attributable owner)
+               public override void AttachTo (Attributable target, IResolveContext context)
                {
                        if (ExplicitTarget == "assembly") {
-                               owners [0] = CodeGen.Assembly;
+                               base.AttachTo (CodeGen.Assembly, context);
                                return;
                        }
+
                        if (ExplicitTarget == "module") {
-                               owners [0] = RootContext.ToplevelTypes;
+                               base.AttachTo (RootContext.ToplevelTypes, context);
                                return;
                        }
+
                        throw new NotImplementedException ("Unknown global explicit target " + ExplicitTarget);
                }
 
@@ -1376,11 +1343,11 @@ namespace Mono.CSharp {
                        RootContext.ToplevelTypes.NamespaceEntry = null;
                }
 
-               protected override TypeExpr ResolveAsTypeTerminal (Expression expr, IResolveContext ec, bool silent)
+               protected override TypeExpr ResolveAsTypeTerminal (Expression expr, IResolveContext ec)
                {
                        try {
                                Enter ();
-                               return base.ResolveAsTypeTerminal (expr, ec, silent);
+                               return base.ResolveAsTypeTerminal (expr, ec);
                        }
                        finally {
                                Leave ();
@@ -1429,10 +1396,10 @@ namespace Mono.CSharp {
                        Attrs.AddRange (attrs);
                }
 
-               public void AttachTo (Attributable attributable)
+               public void AttachTo (Attributable attributable, IResolveContext context)
                {
                        foreach (Attribute a in Attrs)
-                               a.AttachTo (attributable);
+                               a.AttachTo (attributable, context);
                }
 
                public Attributes Clone ()
index a23a20a122cf186f500363663fb6e52710d62706..7fc4aefc64ad2826f13a71cdc0bece4b7c79fb38 100644 (file)
@@ -124,7 +124,7 @@ namespace Mono.CSharp {
                        // During an enum evaluation, none of the rules are valid
                        // Not sure whether it is bug in csc or in documentation
                        //
-                       if (ec.InEnumContext){
+                       if (ec.HasSet (EmitContext.Options.EnumScope)){
                                if (left is EnumConstant)
                                        left = ((EnumConstant) left).Child;
                                
index bcae3c9ea550a8c9782dee192d8285e52350c886..e5858e75c19817f892ca0cd98ae6d47c1ab10246 100644 (file)
@@ -154,6 +154,79 @@ namespace Mono.CSharp {
                        }
                }
 
+               //
+               // Different context is needed when resolving type container base
+               // types. Type names come from the parent scope but type parameter
+               // names from the container scope.
+               //
+               struct BaseContext : IResolveContext
+               {
+                       TypeContainer tc;
+
+                       public BaseContext (TypeContainer tc)
+                       {
+                               this.tc = tc;
+                       }
+
+                       #region IResolveContext Members
+
+                       public Type CurrentType {
+                               get { return tc.Parent.CurrentType; }
+                       }
+
+                       public TypeParameter[] CurrentTypeParameters {
+                               get { return tc.PartialContainer.CurrentTypeParameters; }
+                       }
+
+                       public TypeContainer CurrentTypeDefinition {
+                               get { return tc.Parent.CurrentTypeDefinition; }
+                       }
+
+                       public DeclSpace DeclContainer {
+                               get { return tc.Parent; }
+                       }
+
+                       public bool IsInObsoleteScope {
+                               get { return tc.IsInObsoleteScope; }
+                       }
+
+                       public bool IsInUnsafeScope {
+                               get { return tc.IsInUnsafeScope; }
+                       }
+
+                       public bool IsStatic {
+                               get { return tc.IsStatic; }
+                       }
+
+                       public ExtensionMethodGroupExpr LookupExtensionMethod (Type extensionType, string name, Location loc)
+                       {
+                               return null;
+                       }
+
+                       public FullNamedExpression LookupNamespaceAlias (string name)
+                       {
+                               return tc.Parent.LookupNamespaceAlias (name);
+                       }
+
+                       public FullNamedExpression LookupNamespaceOrType (string name, Location loc, bool ignore_cs0104)
+                       {
+                               TypeParameter[] tp = CurrentTypeParameters;
+                               if (tp != null) {
+                                       TypeParameter t = TypeParameter.FindTypeParameter (tp, name);
+                                       if (t != null)
+                                               return new TypeParameterExpr (t, loc);
+                               }
+
+                               return tc.Parent.LookupNamespaceOrType (name, loc, ignore_cs0104);
+                       }
+
+                       public DeclSpace GenericDeclContainer {
+                               get { return tc.GenericDeclContainer; }
+                       }
+
+                       #endregion
+               }
+
                [Flags]
                enum CachedMethods
                {
@@ -733,33 +806,6 @@ namespace Mono.CSharp {
                        }
                }
 
-               //
-               // Emits the instance field initializers
-               //
-               public bool EmitFieldInitializers (EmitContext ec)
-               {
-                       if (partial_parts != null) {
-                               foreach (TypeContainer part in partial_parts)
-                                       part.EmitFieldInitializers (ec);
-                       }
-
-                       ArrayList fields;
-                       
-                       if (ec.IsStatic){
-                               fields = initialized_static_fields;
-                       } else {
-                               fields = initialized_fields;
-                       }
-
-                       if (fields == null)
-                               return true;
-
-                       foreach (FieldInitializer f in fields) {
-                               f.EmitStatement (ec);
-                       }
-                       return true;
-               }
-               
                public override string DocComment {
                        get {
                                return comment;
@@ -809,6 +855,7 @@ namespace Mono.CSharp {
 
                        int count = type_bases.Count;
                        TypeExpr [] ifaces = null;
+                       IResolveContext base_context = new BaseContext (this);
                        for (int i = 0, j = 0; i < count; i++){
                                FullNamedExpression fne = (FullNamedExpression) type_bases [i];
 
@@ -817,7 +864,7 @@ namespace Mono.CSharp {
                                // it does ObsoleteAttribute and constraint checks which require
                                // base type to be set
                                //
-                               TypeExpr fne_resolved = fne.ResolveAsBaseTerminal (this, false);
+                               TypeExpr fne_resolved = fne.ResolveAsBaseTerminal (base_context, false);
                                if (fne_resolved == null)
                                        continue;
 
@@ -879,7 +926,7 @@ namespace Mono.CSharp {
                                        if (base_class == TypeManager.system_object_expr)
                                                base_class = new_base_class;
                                        else {
-                                               if (new_base_class != null && !new_base_class.Equals (base_class)) {
+                                               if (new_base_class != null && !TypeManager.IsEqual (new_base_class.Type, base_class.Type)) {
                                                        Report.SymbolRelatedToPreviousError (base_class.Location, "");
                                                        Report.Error (263, part.Location,
                                                                "Partial declarations of `{0}' must not specify different base classes",
@@ -982,7 +1029,10 @@ namespace Mono.CSharp {
 #if GMCS_SOURCE
                                GenericTypeParameterBuilder[] gen_params = TypeBuilder.DefineGenericParameters (param_names);
 
-                               int offset = CountTypeParameters - CurrentTypeParameters.Length;
+                               int offset = CountTypeParameters;
+                               if (CurrentTypeParameters != null)
+                                       offset -= CurrentTypeParameters.Length;
+
                                if (offset > 0) {
                                        nested_gen_params = new GenericTypeParameterBuilder [offset];
                                        Array.Copy (gen_params, nested_gen_params, offset);
@@ -1126,9 +1176,9 @@ namespace Mono.CSharp {
 
                void UpdateTypeParameterConstraints (TypeContainer part)
                {
-                       TypeParameter[] current_params = CurrentTypeParameters;
+                       TypeParameter[] current_params = type_params;
                        for (int i = 0; i < current_params.Length; i++) {
-                               Constraints c = part.CurrentTypeParameters [i].Constraints;
+                               Constraints c = part.type_params [i].Constraints;
                                if (c == null)
                                        continue;
 
@@ -1165,17 +1215,18 @@ namespace Mono.CSharp {
                                throw new InternalErrorException ();
 
                        TypeExpr current_type = null;
-
-                       foreach (TypeParameter type_param in CurrentTypeParameters) {
-                               if (!type_param.Resolve (this)) {
-                                       error = true;
-                                       return false;
+                       if (CurrentTypeParameters != null) {
+                               foreach (TypeParameter type_param in CurrentTypeParameters) {
+                                       if (!type_param.Resolve (this)) {
+                                               error = true;
+                                               return false;
+                                       }
                                }
-                       }
 
-                       if (partial_parts != null && is_generic) {
-                               foreach (TypeContainer part in partial_parts)
-                                       UpdateTypeParameterConstraints (part);
+                               if (partial_parts != null) {
+                                       foreach (TypeContainer part in partial_parts)
+                                               UpdateTypeParameterConstraints (part);
+                               }
                        }
 
                        for (int i = 0; i < TypeParameters.Length; ++i) {
@@ -1203,7 +1254,7 @@ namespace Mono.CSharp {
                                return false;
                        }
 
-                       CurrentType = current_type.Type;
+                       currentType = current_type.Type;
                        return true;
                }
 
@@ -1268,6 +1319,12 @@ namespace Mono.CSharp {
                        return true;
                }
 
+               public override TypeParameter[] CurrentTypeParameters {
+                       get {
+                               return PartialContainer.type_params;
+                       }
+               }
+
                /// <summary>
                ///   Populates our TypeBuilder with fields and methods
                /// </summary>
@@ -2639,7 +2696,17 @@ namespace Mono.CSharp {
 
                public override ExtensionMethodGroupExpr LookupExtensionMethod (Type extensionType, string name, Location loc)
                {
-                       return NamespaceEntry.LookupExtensionMethod (extensionType, this, name, loc);
+                       DeclSpace top_level = Parent;
+                       if (top_level != null) {
+                               while (top_level.Parent != null)
+                                       top_level = top_level.Parent;
+
+                               ArrayList candidates = NamespaceEntry.NS.LookupExtensionMethod (extensionType, this, name);
+                               if (candidates != null)
+                                       return new ExtensionMethodGroupExpr (candidates, NamespaceEntry, extensionType, loc);
+                       }
+
+                       return NamespaceEntry.LookupExtensionMethod (extensionType, name, loc);
                }
 
                protected override TypeAttributes TypeAttr {
@@ -2809,7 +2876,7 @@ namespace Mono.CSharp {
                                else if (Name != "System.Object")
                                        base_class = TypeManager.system_object_expr;
                        } else {
-                               if (Kind == Kind.Class && base_class is TypeParameterExpr){
+                               if (Kind == Kind.Class && TypeManager.IsGenericParameter (base_class.Type)){
                                        Report.Error (
                                                689, base_class.Location,
                                                "Cannot derive from `{0}' because it is a type parameter",
@@ -2891,12 +2958,6 @@ namespace Mono.CSharp {
                        return true;
                }
 
-               bool IsStatic {
-                       get {
-                               return (ModFlags & Modifiers.STATIC) != 0;
-                       }
-               }
-
                //
                // FIXME: How do we deal with the user specifying a different
                // layout?
@@ -3562,9 +3623,7 @@ namespace Mono.CSharp {
 
                protected bool DefineParameters (ParametersCompiled parameters)
                {
-                       IResolveContext rc = GenericMethod == null ? this : (IResolveContext)ds;
-
-                       if (!parameters.Resolve (rc))
+                       if (!parameters.Resolve (this))
                                return false;
 
                        bool error = false;
@@ -3776,10 +3835,10 @@ namespace Mono.CSharp {
                        return Parent.MemberCache.CheckExistingMembersOverloads (this, name, Parameters);
                }
 
-               public virtual EmitContext CreateEmitContext (DeclSpace tc, ILGenerator ig)
+               public virtual EmitContext CreateEmitContext (ILGenerator ig)
                {
                        return new EmitContext (
-                               this, tc, this.ds, Location, ig, MemberType, ModFlags, false);
+                               this, this.ds, ig, MemberType);
                }
 
                protected override bool ResolveMemberType ()
@@ -4127,6 +4186,18 @@ namespace Mono.CSharp {
                                        (Parameters[0].ModFlags & ~Parameter.Modifier.PARAMS) == Parameter.Modifier.NONE;
                }
 
+               public override FullNamedExpression LookupNamespaceOrType (string name, Location loc, bool ignore_cs0104)
+               {
+                       TypeParameter[] tp = CurrentTypeParameters;
+                       if (tp != null) {
+                               TypeParameter t = TypeParameter.FindTypeParameter (tp, name);
+                               if (t != null)
+                                       return new TypeParameterExpr (t, loc);
+                       }
+
+                       return base.LookupNamespaceOrType (name, loc, ignore_cs0104);
+               }
+
                public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
                {
                        if (a.Type == pa.Conditional) {
@@ -4212,6 +4283,15 @@ namespace Mono.CSharp {
                        return true;
                }
 
+               public override TypeParameter[] CurrentTypeParameters {
+                       get {
+                               if (GenericMethod != null)
+                                       return GenericMethod.CurrentTypeParameters;
+
+                               return null;
+                       }
+               }
+
                //
                // Creates the type
                //
@@ -4413,23 +4493,36 @@ namespace Mono.CSharp {
                        throw new NotSupportedException ("ET");
                }
 
-               public ExpressionStatement Resolve (ConstructorBuilder caller_builder, EmitContext ec)
+               public override Expression DoResolve (EmitContext ec)
                {
+                       eclass = ExprClass.Value;
+
+                       // TODO: ec.GetSignatureForError ()
+                       ConstructorBuilder caller_builder = ((Constructor) ec.ResolveContext).ConstructorBuilder;
+
                        if (argument_list != null) {
                                bool dynamic;
-                               argument_list.Resolve (ec, out dynamic);
+
+                               //
+                               // Spec mandates that constructor initializer will not have `this' access
+                               //
+                               using (ec.Set (EmitContext.Options.BaseInitializer)) {
+                                       argument_list.Resolve (ec, out dynamic);
+                               }
+
                                if (dynamic) {
                                        SimpleName ctor = new SimpleName (ConstructorBuilder.ConstructorName, loc);
                                        return new DynamicInvocation (ctor, argument_list, loc).Resolve (ec) as ExpressionStatement;
                                }
                        }
 
+                       type = ec.CurrentType;
                        if (this is ConstructorBaseInitializer) {
-                               if (ec.ContainerType.BaseType == null)
+                               if (ec.CurrentType.BaseType == null)
                                        return this;
 
-                               type = ec.ContainerType.BaseType;
-                               if (TypeManager.IsStruct (ec.ContainerType)) {
+                               type = ec.CurrentType.BaseType;
+                               if (TypeManager.IsStruct (ec.CurrentType)) {
                                        Report.Error (522, loc,
                                                "`{0}': Struct constructors cannot call base constructors", TypeManager.CSharpSignature (caller_builder));
                                        return this;
@@ -4441,10 +4534,8 @@ namespace Mono.CSharp {
                                //
                                // struct D { public D (int a) : this () {}
                                //
-                               if (TypeManager.IsStruct (ec.ContainerType) && argument_list == null)
-                                       return this;
-                               
-                               type = ec.ContainerType;
+                               if (TypeManager.IsStruct (ec.CurrentType) && argument_list == null)
+                                       return this;                    
                        }
 
                        base_constructor_group = MemberLookupFinal (
@@ -4460,9 +4551,12 @@ namespace Mono.CSharp {
                        
                        if (base_constructor_group == null)
                                return this;
+
+                       if (!ec.IsStatic)
+                               base_constructor_group.InstanceExpression = ec.GetThis (loc);
                        
                        ConstructorInfo base_ctor = (ConstructorInfo)base_constructor_group;
-                       
+
                        if (base_ctor == caller_builder){
                                Report.Error (516, loc, "Constructor `{0}' cannot call itself", TypeManager.CSharpSignature (caller_builder));
                        }
@@ -4470,11 +4564,6 @@ namespace Mono.CSharp {
                        return this;
                }
 
-               public override Expression DoResolve (EmitContext ec)
-               {
-                       throw new NotSupportedException ();
-               }
-
                public override void Emit (EmitContext ec)
                {
                        // It can be null for static initializers
@@ -4482,9 +4571,7 @@ namespace Mono.CSharp {
                                return;
                        
                        ec.Mark (loc);
-                       if (!ec.IsStatic)
-                               base_constructor_group.InstanceExpression = ec.GetThis (loc);
-                       
+
                        base_constructor_group.EmitCall (ec, argument_list);
                }
 
@@ -4692,7 +4779,7 @@ namespace Mono.CSharp {
 
                        base.Emit ();
 
-                       EmitContext ec = CreateEmitContext (null, null);
+                       EmitContext ec = CreateEmitContext (null);
 
                        //
                        // If we use a "this (...)" constructor initializer, then
@@ -4711,44 +4798,24 @@ namespace Mono.CSharp {
                                        ((ModFlags & Modifiers.STATIC) == 0) && (Initializer == null))
                                        block.AddThisVariable (Parent, Location);
 
-                               if (!block.ResolveMeta (ec, Parameters))
-                                       block = null;
-
                                if (block != null && (ModFlags & Modifiers.STATIC) == 0){
                                        if (Parent.PartialContainer.Kind == Kind.Class && Initializer == null)
                                                Initializer = new GeneratedBaseInitializer (Location);
 
-                                       //
-                                       // Spec mandates that Initializers will not have `this' access
-                                       //
                                        if (Initializer != null) {
-                                               ec.IsStatic = true;
-                                               ExpressionStatement expr = Initializer.Resolve (ConstructorBuilder, ec);
-                                               ec.IsStatic = false;
-                                               block.AddScopeStatement (new StatementExpression (expr));
+                                               block.AddScopeStatement (new StatementExpression (Initializer));
                                        }
                                }
                        }
 
                        Parameters.ApplyAttributes (ConstructorBuilder);
-                       
-                       SourceMethod source = null;
-                       if (block == null)
-                               ec.OmitDebuggingInfo = true;
-                       else
-                               source = SourceMethod.Create (Parent, ConstructorBuilder, block);
-
-                       bool unreachable = false;
-                       if (block != null) {
-                               if (!ec.ResolveTopBlock (null, block, Parameters, this, out unreachable))
-                                       return;
 
-                               ec.EmitMeta (block);
+                       SourceMethod source = SourceMethod.Create (Parent, ConstructorBuilder, block);
 
-                               if (Report.Errors > 0)
-                                       return;
-
-                               ec.EmitResolvedTopBlock (block, unreachable);
+                       if (block != null) {
+                               if (block.Resolve (null, ec, Parameters, this)) {
+                                       block.Emit (ec);
+                               }
                        }
 
                        if (source != null)
@@ -4817,11 +4884,12 @@ namespace Mono.CSharp {
                        }
                }
 
-               public EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig)
+               public EmitContext CreateEmitContext (ILGenerator ig)
                {
                        ILGenerator ig_ = ConstructorBuilder.GetILGenerator ();
-                       EmitContext ec = new EmitContext (this, Parent, Location, ig_, TypeManager.void_type, ModFlags, true);
+                       EmitContext ec = new EmitContext (this, Parent, ig_, TypeManager.void_type);
                        ec.CurrentBlock = block;
+                       ec.Set (EmitContext.Options.ConstructorScope);
                        return ec;
                }
 
@@ -4857,7 +4925,7 @@ namespace Mono.CSharp {
                Attributes OptAttributes { get; }
                ToplevelBlock Block { get; set; }
 
-               EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig);
+               EmitContext CreateEmitContext (ILGenerator ig);
                ObsoleteAttribute GetObsoleteAttribute ();
                string GetSignatureForError ();
                bool IsExcluded ();
@@ -5075,7 +5143,7 @@ namespace Mono.CSharp {
                                if (implementing != null)
                                        parent_method = implementing;
 
-                               EmitContext ec = method.CreateEmitContext (container, null);
+                               EmitContext ec = method.CreateEmitContext (null);
                                if (!GenericMethod.DefineType (ec, builder, parent_method, is_override))
                                        return false;
                        }
@@ -5121,14 +5189,6 @@ namespace Mono.CSharp {
                // 
                public void Emit (DeclSpace parent)
                {
-                       ToplevelBlock block = method.Block;
-
-                       EmitContext ec;
-                       if (block != null)
-                               ec = method.CreateEmitContext (parent, builder.GetILGenerator ());
-                       else
-                               ec = method.CreateEmitContext (parent, null);
-
                        method.ParameterInfo.ApplyAttributes (MethodBuilder);
 
                        if (GenericMethod != null)
@@ -5143,7 +5203,13 @@ namespace Mono.CSharp {
 
                        SourceMethod source = SourceMethod.Create (parent, MethodBuilder, method.Block);
 
-                       ec.EmitTopBlock (method, block);
+                       ToplevelBlock block = method.Block;
+                       if (block != null) {
+                               EmitContext ec = method.CreateEmitContext (builder.GetILGenerator ());
+                               if (block.Resolve (null, ec, method.ParameterInfo, method)) {
+                                       block.Emit (ec);
+                               }
+                       }
 
                        if (source != null) {
                                method.EmitExtraSymbolInfo (source);
@@ -5652,7 +5718,7 @@ namespace Mono.CSharp {
 
                public override void Emit()
                {
-                       EmitContext ec = new EmitContext (this, Parent, Location, null, TypeManager.void_type, ModFlags);
+                       EmitContext ec = new EmitContext (this, Parent, null, TypeManager.void_type);
                        Constant c = size_expr.ResolveAsConstant (ec, this);
                        if (c == null)
                                return;
@@ -6022,7 +6088,7 @@ namespace Mono.CSharp {
 
                public abstract ParametersCompiled ParameterInfo { get ; }
                public abstract Type ReturnType { get; }
-               public abstract EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig);
+               public abstract EmitContext CreateEmitContext (ILGenerator ig);
 
                #endregion
 
@@ -6249,7 +6315,7 @@ namespace Mono.CSharp {
 
                        public override MethodBuilder Define (DeclSpace parent)
                        {
-                               parameters.Resolve (ResolveContext);
+                               parameters.Resolve (this);
                                
                                base.Define (parent);
 
@@ -6384,11 +6450,10 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       public override EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig)
+                       public override EmitContext CreateEmitContext (ILGenerator ig)
                        {
                                return new EmitContext (this,
-                                       ds, method.ds, method.Location, ig, ReturnType,
-                                       method.ModFlags, false);
+                                       method.ds, ig, ReturnType);
                        }
 
                        public override ObsoleteAttribute GetObsoleteAttribute ()
@@ -7240,11 +7305,10 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       public override EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig)
+                       public override EmitContext CreateEmitContext (ILGenerator ig)
                        {
                                return new EmitContext (
-                                       this, method.Parent, Location, ig, ReturnType,
-                                       method.ModFlags, false);
+                                       this, method.Parent, ig, ReturnType);
                        }
 
                        public override ObsoleteAttribute GetObsoleteAttribute ()
@@ -7420,7 +7484,7 @@ namespace Mono.CSharp {
 
                        public override MethodBuilder Define (DeclSpace parent)
                        {
-                               parameters.Resolve (ResolveContext);
+                               parameters.Resolve (this);
                                return base.Define (parent);
                        }
                        
index 39adbb4fa8c9ad12fb75bb7c4265b14fdf6921d6..a261d3d97345498e90f72414d20c1bf6ae19c5e0 100644 (file)
@@ -253,9 +253,31 @@ namespace Mono.CSharp {
        /// </summary>
        public interface IResolveContext
        {
-               DeclSpace DeclContainer { get; }
+               //
+               // A scope type context, it can be inflated for generic types
+               //
+               Type CurrentType { get; }
+
+               //
+               // A scope type parameters either VAR or MVAR
+               //
+               TypeParameter[] CurrentTypeParameters { get; }
+
+               //
+               // A type definition of the type context. For partial types definition use
+               // CurrentTypeDefinition.PartialContainer otherwise the context is local
+               //
+               // TODO: CurrentType.Definition
+               //
+               TypeContainer CurrentTypeDefinition { get; }
+
                bool IsInObsoleteScope { get; }
                bool IsInUnsafeScope { get; }
+               bool IsStatic { get; }
+
+               ExtensionMethodGroupExpr LookupExtensionMethod (Type extensionType, string name, Location loc);
+               FullNamedExpression LookupNamespaceOrType (string name, Location loc, bool ignore_cs0104);
+               FullNamedExpression LookupNamespaceAlias (string name);
 
                // the declcontainer to lookup for type-parameters.  Should only use LookupGeneric on it.
                //
@@ -272,18 +294,9 @@ namespace Mono.CSharp {
        /// </summary>
        public class EmitContext : IResolveContext {
 
-               //
-               // Holds a varible used during collection or object initialization.
-               //
-               public Expression CurrentInitializerVariable;
-
-               DeclSpace decl_space;
-               
-               public DeclSpace TypeContainer;
-               public ILGenerator ig;
-
                [Flags]
-               public enum Flags : int {
+               public enum Options
+               {
                        /// <summary>
                        ///   This flag tracks the `checked' state of the compilation,
                        ///   it controls whether we should generate code that does overflow
@@ -294,7 +307,7 @@ namespace Mono.CSharp {
                        ///   checked/unchecked statements or expressions.   Contrast this with
                        ///   the ConstantCheckState flag.
                        /// </summary>
-                       CheckState = 1 << 0,
+                       CheckedScope = 1 << 0,
 
                        /// <summary>
                        ///   The constant check state is always set to `true' and cant be changed
@@ -303,60 +316,101 @@ namespace Mono.CSharp {
                        /// </summary>
                        ConstantCheckState = 1 << 1,
 
-                       AllCheckStateFlags = CheckState | ConstantCheckState,
+                       AllCheckStateFlags = CheckedScope | ConstantCheckState,
 
-                       /// <summary>
-                       ///  Whether we are inside an unsafe block
-                       /// </summary>
-                       InUnsafe = 1 << 2,
+                       //
+                       // unsafe { ... } scope
+                       //
+                       UnsafeScope = 1 << 2,
+                       CatchScope = 1 << 3,
+                       FinallyScope = 1 << 4,
+                       FieldInitializerScope = 1 << 5,
+                       CompoundAssignmentScope = 1 << 6,
+                       FixedInitializerScope = 1 << 7,
+                       BaseInitializer = 1 << 8,
 
-                       InCatch = 1 << 3,
-                       InFinally = 1 << 4,
+                       //
+                       // Inside an enum definition, we do not resolve enumeration values
+                       // to their enumerations, but rather to the underlying type/value
+                       // This is so EnumVal + EnumValB can be evaluated.
+                       //
+                       // There is no "E operator + (E x, E y)", so during an enum evaluation
+                       // we relax the rules
+                       //
+                       EnumScope = 1 << 9,
+
+                       ConstantScope = 1 << 10,
+
+                       ConstructorScope = 1 << 11,
 
                        /// <summary>
                        ///   Whether control flow analysis is enabled
                        /// </summary>
-                       DoFlowAnalysis = 1 << 5,
+                       DoFlowAnalysis = 1 << 20,
 
                        /// <summary>
                        ///   Whether control flow analysis is disabled on structs
                        ///   (only meaningful when DoFlowAnalysis is set)
                        /// </summary>
-                       OmitStructFlowAnalysis = 1 << 6,
+                       OmitStructFlowAnalysis = 1 << 21,
 
                        ///
                        /// Indicates the current context is in probing mode, no errors are reported. 
                        ///
-                       ProbingMode = 1 <<      7,
+                       ProbingMode = 1 <<      22,
 
                        //
-                       // Inside field intializer expression
+                       // Return and ContextualReturn statements will set the ReturnType
+                       // value based on the expression types of each return statement
+                       // instead of the method return type which is initially null.
                        //
-                       InFieldInitializer = 1 << 8,
-                       
-                       InferReturnType = 1 << 9,
-                       
-                       InCompoundAssignment = 1 << 10,
+                       InferReturnType = 1 << 23,
 
-                       OmitDebuggingInfo = 1 << 11
+                       OmitDebuggingInfo = 1 << 24
                }
 
-               Flags flags;
+               // utility helper for CheckExpr, UnCheckExpr, Checked and Unchecked statements
+               // it's public so that we can use a struct at the callsite
+               public struct FlagsHandle : IDisposable
+               {
+                       EmitContext ec;
+                       readonly Options invmask, oldval;
 
-               /// <summary>
-               ///   Whether we are emitting code inside a static or instance method
-               /// </summary>
-               public bool IsStatic;
+                       public FlagsHandle (EmitContext ec, Options flagsToSet)
+                               : this (ec, flagsToSet, flagsToSet)
+                       {
+                       }
 
-               /// <summary>
-               ///   Whether the actual created method is static or instance method.
-               ///   Althoug the method might be declared as `static', if an anonymous
-               ///   method is involved, we might turn this into an instance method.
-               ///
-               ///   So this reflects the low-level staticness of the method, while
-               ///   IsStatic represents the semantic, high-level staticness.
-               /// </summary>
-               //public bool MethodIsStatic;
+                       internal FlagsHandle (EmitContext ec, Options mask, Options val)
+                       {
+                               this.ec = ec;
+                               invmask = ~mask;
+                               oldval = ec.flags & mask;
+                               ec.flags = (ec.flags & invmask) | (val & mask);
+
+                               if ((mask & Options.ProbingMode) != 0)
+                                       Report.DisableReporting ();
+                       }
+
+                       public void Dispose ()
+                       {
+                               if ((invmask & Options.ProbingMode) == 0)
+                                       Report.EnableReporting ();
+
+                               ec.flags = (ec.flags & invmask) | oldval;
+                       }
+               }
+
+               Options flags;
+
+               //
+               // Holds a varible used during collection or object initialization.
+               //
+               public Expression CurrentInitializerVariable;
+
+               DeclSpace decl_space;
+
+               public ILGenerator ig;
 
                /// <summary>
                ///   The value that is allowed to be returned or NULL if there is no
@@ -364,17 +418,6 @@ namespace Mono.CSharp {
                /// </summary>
                Type return_type;
 
-               /// <summary>
-               ///   Points to the Type (extracted from the TypeContainer) that
-               ///   declares this body of code
-               /// </summary>
-               public readonly Type ContainerType;
-               
-               /// <summary>
-               ///   Whether this is generating code for a constructor
-               /// </summary>
-               public bool IsConstructor;
-
                /// <summary>
                ///   Keeps track of the Type to LocalBuilder temporary storage created
                ///   to store structures (used to compute the address of the structure
@@ -384,12 +427,10 @@ namespace Mono.CSharp {
 
                public Block CurrentBlock;
 
-               public int CurrentFile;
-
                /// <summary>
                ///   The location where we store the return value.
                /// </summary>
-               LocalBuilder return_value;
+               public LocalBuilder return_value;
 
                /// <summary>
                ///   The location where return has to jump to return the
@@ -402,31 +443,11 @@ namespace Mono.CSharp {
                /// </summary>
                public bool HasReturnLabel;
 
-               /// <summary>
-               ///  Whether we are in a `fixed' initialization
-               /// </summary>
-               public bool InFixedInitializer;
-
                /// <summary>
                ///  Whether we are inside an anonymous method.
                /// </summary>
                public AnonymousExpression CurrentAnonymousMethod;
                
-               /// <summary>
-               ///   Location for this EmitContext
-               /// </summary>
-               public Location loc;
-
-               /// <summary>
-               ///   Inside an enum definition, we do not resolve enumeration values
-               ///   to their enumerations, but rather to the underlying type/value
-               ///   This is so EnumVal + EnumValB can be evaluated.
-               ///
-               ///   There is no "E operator + (E x, E y)", so during an enum evaluation
-               ///   we relax the rules
-               /// </summary>
-               public bool InEnumContext;
-
                public readonly IResolveContext ResolveContext;
 
                /// <summary>
@@ -436,172 +457,100 @@ namespace Mono.CSharp {
                        get { return CurrentAnonymousMethod as Iterator; }
                }
 
-               /// <summary>
-               ///    Whether we are in the resolving stage or not
-               /// </summary>
-               enum Phase {
-                       Created,
-                       Resolving,
-                       Emitting
-               }
-
-               bool isAnonymousMethodAllowed = true;
-
-               Phase current_phase;
                FlowBranching current_flow_branching;
 
-               static int next_id = 0;
-               int id = ++next_id;
+               public TypeInferenceContext ReturnTypeInference;
 
-               public override string ToString ()
-               {
-                       return String.Format ("EmitContext ({0}:{1})", id,
-                                             CurrentAnonymousMethod, loc);
-               }
-               
-               public EmitContext (IResolveContext rc, DeclSpace parent, DeclSpace ds, Location l, ILGenerator ig,
-                                   Type return_type, int code_flags, bool is_constructor)
+//             static int next_id = 0;
+//             int id = ++next_id;
+
+               public EmitContext (IResolveContext rc, DeclSpace ds, ILGenerator ig,
+                                   Type return_type)
                {
                        this.ResolveContext = rc;
                        this.ig = ig;
 
-                       TypeContainer = parent;
                        this.decl_space = ds;
+
+                       //
+                       // The default setting comes from the command line option
+                       //
                        if (RootContext.Checked)
-                               flags |= Flags.CheckState;
-                       flags |= Flags.ConstantCheckState;
+                               flags |= Options.CheckedScope;
+
+                       //
+                       // The constant check state is always set to true
+                       //
+                       flags |= Options.ConstantCheckState;
 
                        if (return_type == null)
                                throw new ArgumentNullException ("return_type");
 
-                       IsStatic = (code_flags & Modifiers.STATIC) != 0;
                        ReturnType = return_type;
-                       IsConstructor = is_constructor;
-                       CurrentBlock = null;
-                       CurrentFile = 0;
-                       current_phase = Phase.Created;
-
-                       if (parent != null){
-                               // Can only be null for the ResolveType contexts.
-                               ContainerType = parent.TypeBuilder;
-                               if (rc.IsInUnsafeScope)
-                                       flags |= Flags.InUnsafe;
-                       }
-                       loc = l;
                }
 
-               public EmitContext (IResolveContext rc, DeclSpace ds, Location l, ILGenerator ig,
-                                   Type return_type, int code_flags, bool is_constructor)
-                       : this (rc, ds, ds, l, ig, return_type, code_flags, is_constructor)
-               {
+               public Type CurrentType {
+                       get { return ResolveContext.CurrentType; }
                }
 
-               public EmitContext (IResolveContext rc, DeclSpace ds, Location l, ILGenerator ig,
-                                   Type return_type, int code_flags)
-                       : this (rc, ds, ds, l, ig, return_type, code_flags, false)
-               {
+               public TypeParameter[] CurrentTypeParameters {
+                       get { return ResolveContext.CurrentTypeParameters; }
                }
 
-               // IResolveContext.DeclContainer
-               public DeclSpace DeclContainer { 
-                       get { return decl_space; }
-                       set { decl_space = value; }
+               public TypeContainer CurrentTypeDefinition {
+                       get { return ResolveContext.CurrentTypeDefinition; }
                }
 
                // IResolveContext.GenericDeclContainer
                public DeclSpace GenericDeclContainer {
-                       get { return DeclContainer; }
-               }
-
-               public bool CheckState {
-                       get { return (flags & Flags.CheckState) != 0; }
+                       get { return decl_space; }
                }
 
                public bool ConstantCheckState {
-                       get { return (flags & Flags.ConstantCheckState) != 0; }
+                       get { return (flags & Options.ConstantCheckState) != 0; }
                }
 
                public bool InUnsafe {
-                       get { return (flags & Flags.InUnsafe) != 0; }
-               }
-
-               public bool InCatch {
-                       get { return (flags & Flags.InCatch) != 0; }
-               }
-
-               public bool InFinally {
-                       get { return (flags & Flags.InFinally) != 0; }
+                       get { return HasSet (Options.UnsafeScope) || ResolveContext.IsInUnsafeScope; }
                }
 
                public bool DoFlowAnalysis {
-                       get { return (flags & Flags.DoFlowAnalysis) != 0; }
+                       get { return (flags & Options.DoFlowAnalysis) != 0; }
                }
 
                public bool OmitStructFlowAnalysis {
-                       get { return (flags & Flags.OmitStructFlowAnalysis) != 0; }
+                       get { return (flags & Options.OmitStructFlowAnalysis) != 0; }
                }
 
-               // utility helper for CheckExpr, UnCheckExpr, Checked and Unchecked statements
-               // it's public so that we can use a struct at the callsite
-               public struct FlagsHandle : IDisposable
+               public bool HasSet (Options options)
                {
-                       EmitContext ec;
-                       readonly Flags invmask, oldval;
-
-                       public FlagsHandle (EmitContext ec, Flags flagsToSet)
-                               : this (ec, flagsToSet, flagsToSet)
-                       {
-                       }
-
-                       internal FlagsHandle (EmitContext ec, Flags mask, Flags val)
-                       {
-                               this.ec = ec;
-                               invmask = ~mask;
-                               oldval = ec.flags & mask;
-                               ec.flags = (ec.flags & invmask) | (val & mask);
-
-                               if ((mask & Flags.ProbingMode) != 0)
-                                       Report.DisableReporting ();
-                       }
-
-                       public void Dispose ()
-                       {
-                               if ((invmask & Flags.ProbingMode) == 0)
-                                       Report.EnableReporting ();
+                       return (this.flags & options) == options;
+               }
 
-                               ec.flags = (ec.flags & invmask) | oldval;
-                       }
+               public bool HasAny (Options options)
+               {
+                       return (this.flags & options) != 0;
                }
 
                // Temporarily set all the given flags to the given value.  Should be used in an 'using' statement
-               public FlagsHandle Set (Flags flagsToSet)
+               public FlagsHandle Set (Options options)
                {
-                       return new FlagsHandle (this, flagsToSet);
+                       return new FlagsHandle (this, options);
                }
 
-               public FlagsHandle With (Flags bits, bool enable)
+               public FlagsHandle With (Options options, bool enable)
                {
-                       return new FlagsHandle (this, bits, enable ? bits : 0);
+                       return new FlagsHandle (this, options, enable ? options : 0);
                }
 
                public FlagsHandle WithFlowAnalysis (bool do_flow_analysis, bool omit_struct_analysis)
                {
-                       Flags newflags = 
-                               (do_flow_analysis ? Flags.DoFlowAnalysis : 0) |
-                               (omit_struct_analysis ? Flags.OmitStructFlowAnalysis : 0);
-                       return new FlagsHandle (this, Flags.DoFlowAnalysis | Flags.OmitStructFlowAnalysis, newflags);
+                       Options newflags = 
+                               (do_flow_analysis ? Options.DoFlowAnalysis : 0) |
+                               (omit_struct_analysis ? Options.OmitStructFlowAnalysis : 0);
+                       return new FlagsHandle (this, Options.DoFlowAnalysis | Options.OmitStructFlowAnalysis, newflags);
                }
                
-               /// <summary>
-               ///   If this is true, then Return and ContextualReturn statements
-               ///   will set the ReturnType value based on the expression types
-               ///   of each return statement instead of the method return type
-               ///   (which is initially null).
-               /// </summary>
-               public bool InferReturnType {
-                       get { return (flags & Flags.InferReturnType) != 0; }
-               }
-
                // IResolveContext.IsInObsoleteScope
                public bool IsInObsoleteScope {
                        get {
@@ -611,25 +560,17 @@ namespace Mono.CSharp {
                }
 
                public bool IsInProbingMode {
-                       get { return (flags & Flags.ProbingMode) != 0; }
+                       get { return (flags & Options.ProbingMode) != 0; }
                }
 
-               // IResolveContext.IsInUnsafeScope
-               public bool IsInUnsafeScope {
-                       get { return InUnsafe || ResolveContext.IsInUnsafeScope; }
+               bool IResolveContext.IsInUnsafeScope {
+                       get { return InUnsafe; }
                }
 
-               public bool IsAnonymousMethodAllowed {
-                       get { return isAnonymousMethodAllowed; }
-                       set { isAnonymousMethodAllowed = value; }
-               }
-
-               public bool IsInFieldInitializer {
-                       get { return (flags & Flags.InFieldInitializer) != 0; }
-               }
-               
-               public bool IsInCompoundAssignment {
-                       get { return (flags & Flags.InCompoundAssignment) != 0; }
+               // TODO: Hopefully temporary hack for anonyous methods, ResolveContext != EmitContext
+               public object AnonymousStatic;
+               public bool IsStatic {
+                       get { return AnonymousStatic != null ? (bool) AnonymousStatic : ResolveContext.IsStatic; }
                }
 
                public bool IsVariableCapturingRequired {
@@ -643,12 +584,12 @@ namespace Mono.CSharp {
                }
 
                public bool OmitDebuggingInfo {
-                       get { return (flags & Flags.OmitDebuggingInfo) != 0; }
+                       get { return (flags & Options.OmitDebuggingInfo) != 0; }
                        set {
                                if (value)
-                                       flags |= Flags.OmitDebuggingInfo;
+                                       flags |= Options.OmitDebuggingInfo;
                                else
-                                       flags &= ~Flags.OmitDebuggingInfo;
+                                       flags &= ~Options.OmitDebuggingInfo;
                        }
                }
 
@@ -667,7 +608,7 @@ namespace Mono.CSharp {
                // </summary>
                public FlowBranching StartFlowBranching (Block block)
                {
-                       flags |= Flags.DoFlowAnalysis;
+                       flags |= Options.DoFlowAnalysis;
 
                        current_flow_branching = FlowBranching.CreateBranching (
                                CurrentBranching, FlowBranching.BranchingType.Block, block, block.StartLocation);
@@ -702,9 +643,9 @@ namespace Mono.CSharp {
                        return branching;
                }
 
-               public FlowBranchingToplevel StartFlowBranching (ToplevelBlock stmt)
+               public FlowBranchingToplevel StartFlowBranching (ToplevelBlock stmt, FlowBranching parent)
                {
-                       FlowBranchingToplevel branching = new FlowBranchingToplevel (CurrentBranching, stmt);
+                       FlowBranchingToplevel branching = new FlowBranchingToplevel (parent, stmt);
                        current_flow_branching = branching;
                        return branching;
                }
@@ -745,119 +686,6 @@ namespace Mono.CSharp {
                        return local.Block.Toplevel != CurrentBlock.Toplevel;
                }
                
-               public void EmitMeta (ToplevelBlock b)
-               {
-                       b.EmitMeta (this);
-
-                       if (HasReturnLabel)
-                               ReturnLabel = ig.DefineLabel ();
-               }
-
-               //
-               // Here until we can fix the problem with Mono.CSharp.Switch, which
-               // currently can not cope with ig == null during resolve (which must
-               // be fixed for switch statements to work on anonymous methods).
-               //
-               public void EmitTopBlock (IMethodData md, ToplevelBlock block)
-               {
-                       if (block == null)
-                               return;
-                       
-                       bool unreachable;
-                       
-                       if (ResolveTopBlock (null, block, md.ParameterInfo, md, out unreachable)){
-                               if (Report.Errors > 0)
-                                       return;
-
-                               EmitMeta (block);
-
-                               current_phase = Phase.Emitting;
-#if PRODUCTION
-                               try {
-#endif
-                               EmitResolvedTopBlock (block, unreachable);
-#if PRODUCTION
-                               } catch (Exception e){
-                                       Console.WriteLine ("Exception caught by the compiler while emitting:");
-                                       Console.WriteLine ("   Block that caused the problem begin at: " + block.loc);
-                                       
-                                       Console.WriteLine (e.GetType ().FullName + ": " + e.Message);
-                                       throw;
-                               }
-#endif
-                       }
-               }
-
-               bool resolved;
-               bool unreachable;
-               
-               public bool ResolveTopBlock (EmitContext anonymous_method_host, ToplevelBlock block,
-                                            ParametersCompiled ip, IMethodData md, out bool unreachable)
-               {
-                       if (resolved) {
-                               unreachable = this.unreachable;
-                               return true;
-                       }
-
-                       current_phase = Phase.Resolving;
-                       unreachable = false;
-
-                       if (!loc.IsNull)
-                               CurrentFile = loc.File;
-
-#if PRODUCTION
-                       try {
-#endif
-                               if (!block.ResolveMeta (this, ip))
-                                       return false;
-
-                               using (this.With (EmitContext.Flags.DoFlowAnalysis, true)) {
-                                       FlowBranchingToplevel top_level;
-                                       if (anonymous_method_host != null)
-                                               top_level = new FlowBranchingToplevel (anonymous_method_host.CurrentBranching, block);
-                                       else 
-                                               top_level = block.TopLevelBranching;
-
-                                       current_flow_branching = top_level;
-                                       bool ok = block.Resolve (this);
-                                       current_flow_branching = null;
-
-                                       if (!ok)
-                                               return false;
-
-                                       bool flow_unreachable = top_level.End ();
-                                       if (flow_unreachable)
-                                               this.unreachable = unreachable = true;
-                               }
-#if PRODUCTION
-                       } catch (Exception e) {
-                               Console.WriteLine ("Exception caught by the compiler while compiling:");
-                               Console.WriteLine ("   Block that caused the problem begin at: " + loc);
-
-                               if (CurrentBlock != null){
-                                       Console.WriteLine ("                     Block being compiled: [{0},{1}]",
-                                                          CurrentBlock.StartLocation, CurrentBlock.EndLocation);
-                               }
-                               Console.WriteLine (e.GetType ().FullName + ": " + e.Message);
-                               throw;
-                       }
-#endif
-
-                       if (return_type != TypeManager.void_type && !unreachable) {
-                               if (CurrentAnonymousMethod == null) {
-                                       Report.Error (161, md.Location, "`{0}': not all code paths return a value", md.GetSignatureForError ());
-                                       return false;
-                               } else if (!CurrentAnonymousMethod.IsIterator) {
-                                       Report.Error (1643, CurrentAnonymousMethod.Location, "Not all code paths return a value in anonymous method of type `{0}'",
-                                                     CurrentAnonymousMethod.GetSignatureForError ());
-                                       return false;
-                               }
-                       }
-
-                       resolved = true;
-                       return true;
-               }
-
                public Type ReturnType {
                        set {
                                return_type = value;
@@ -867,39 +695,6 @@ namespace Mono.CSharp {
                        }
                }
 
-               public void EmitResolvedTopBlock (ToplevelBlock block, bool unreachable)
-               {
-                       if (block != null)
-                               block.Emit (this);
-
-                       if (HasReturnLabel)
-                               ig.MarkLabel (ReturnLabel);
-
-                       if (return_value != null){
-                               ig.Emit (OpCodes.Ldloc, return_value);
-                               ig.Emit (OpCodes.Ret);
-                       } else {
-                               //
-                               // If `HasReturnLabel' is set, then we already emitted a
-                               // jump to the end of the method, so we must emit a `ret'
-                               // there.
-                               //
-                               // Unfortunately, System.Reflection.Emit automatically emits
-                               // a leave to the end of a finally block.  This is a problem
-                               // if no code is following the try/finally block since we may
-                               // jump to a point after the end of the method.
-                               // As a workaround, we're always creating a return label in
-                               // this case.
-                               //
-
-                               if (HasReturnLabel || !unreachable) {
-                                       if (return_type != TypeManager.void_type)
-                                               ig.Emit (OpCodes.Ldloc, TemporaryReturn ());
-                                       ig.Emit (OpCodes.Ret);
-                               }
-                       }
-               }
-
                /// <summary>
                ///   This is called immediately before emitting an IL opcode to tell the symbol
                ///   writer to which source line this opcode belongs.
@@ -1019,13 +814,13 @@ namespace Mono.CSharp {
                /// </summary>
                public void NeedReturnLabel ()
                {
-                       if (current_phase != Phase.Resolving){
+//                     if (current_phase != Phase.Resolving){
                                //
                                // The reason is that the `ReturnLabel' is declared between
                                // resolution and emission
                                // 
-                               throw new Exception ("NeedReturnLabel called from Emit phase, should only be called during Resolve");
-                       }
+//                             throw new Exception ("NeedReturnLabel called from Emit phase, should only be called during Resolve");
+//                     }
                        
                        if (!HasReturnLabel)
                                HasReturnLabel = true;
@@ -1045,20 +840,34 @@ namespace Mono.CSharp {
 
                        return my_this;
                }
-       }
 
+               #region IResolveContext Members
 
-       public abstract class CommonAssemblyModulClass : Attributable, IResolveContext {
+               public ExtensionMethodGroupExpr LookupExtensionMethod (Type extensionType, string name, Location loc)
+               {
+                       return ResolveContext.LookupExtensionMethod (extensionType, name, loc);
+               }
 
-               protected CommonAssemblyModulClass ():
-                       base (null)
+               public FullNamedExpression LookupNamespaceOrType (string name, Location loc, bool ignore_cs0104)
                {
+                       return ResolveContext.LookupNamespaceOrType (name, loc, ignore_cs0104);
                }
 
-               public void AddAttributes (ArrayList attrs)
+               public FullNamedExpression LookupNamespaceAlias (string name)
+               {
+                       return ResolveContext.LookupNamespaceAlias (name);
+               }
+
+               #endregion
+       }
+
+
+       public abstract class CommonAssemblyModulClass : Attributable, IResolveContext
+       {
+               public void AddAttributes (ArrayList attrs, IResolveContext context)
                {
                        foreach (Attribute a in attrs)
-                               a.AttachTo (this);
+                               a.AttachTo (this, context);
 
                        if (attributes == null) {
                                attributes = new Attributes (attrs);
@@ -1084,11 +893,19 @@ namespace Mono.CSharp {
                        return a;
                }
 
-               public override IResolveContext ResolveContext {
-                       get { return this; }
+               #region IResolveContext Members
+
+               public Type CurrentType {
+                       get { return null; }
                }
 
-               #region IResolveContext Members
+               public TypeParameter[] CurrentTypeParameters {
+                       get { return null; }
+               }
+
+               public TypeContainer CurrentTypeDefinition {
+                       get { throw new InternalErrorException ("No TypeContainer in module context"); }
+               }
 
                public DeclSpace DeclContainer {
                        get { return RootContext.ToplevelTypes; }
@@ -1106,6 +923,25 @@ namespace Mono.CSharp {
                        get { return false; }
                }
 
+               public bool IsStatic {
+                       get { return false; }
+               }
+
+               public ExtensionMethodGroupExpr LookupExtensionMethod (Type extensionType, string name, Location loc)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public FullNamedExpression LookupNamespaceOrType (string name, Location loc, bool ignore_cs0104)
+               {
+                       return RootContext.ToplevelTypes.LookupNamespaceOrType (name, loc, ignore_cs0104);
+               }
+
+               public FullNamedExpression LookupNamespaceAlias (string name)
+               {
+                       return null;
+               }
+
                #endregion
        }
                 
@@ -1179,9 +1015,10 @@ namespace Mono.CSharp {
                                Arguments named = new Arguments (1);
                                named.Add (new NamedArgument (new LocatedToken (loc, "SkipVerification"), (new BoolLiteral (true, loc))));
 
-                               GlobalAttribute g = new GlobalAttribute (new NamespaceEntry (null, null, null), "assembly", system_security_permissions,
-                                       "SecurityPermissionAttribute", new Arguments[] { pos, named }, loc, false);
-                               g.AttachTo (this);
+                               GlobalAttribute g = new GlobalAttribute (new NamespaceEntry (null, null, null), "assembly",
+                                       new MemberAccess (system_security_permissions, "SecurityPermissionAttribute"),
+                                       new Arguments[] { pos, named }, loc, false);
+                               g.AttachTo (this, this);
 
                                if (g.Resolve () != null) {
                                        declarative_security = new ListDictionary ();
@@ -1258,7 +1095,7 @@ namespace Mono.CSharp {
                                        case "AssemblyKeyFileAttribute":
                                        case "System.Reflection.AssemblyKeyFileAttribute":
                                                if (RootContext.StrongNameKeyFile != null) {
-                                                       Report.SymbolRelatedToPreviousError (a.Location, a.Name);
+                                                       Report.SymbolRelatedToPreviousError (a.Location, a.GetSignatureForError ());
                                                        Report.Warning (1616, 1, "Option `{0}' overrides attribute `{1}' given in a source file or added module",
                                                                        "keyfile", "System.Reflection.AssemblyKeyFileAttribute");
                                                } else {
@@ -1271,7 +1108,7 @@ namespace Mono.CSharp {
                                        case "AssemblyKeyNameAttribute":
                                        case "System.Reflection.AssemblyKeyNameAttribute":
                                                if (RootContext.StrongNameKeyContainer != null) {
-                                                       Report.SymbolRelatedToPreviousError (a.Location, a.Name);
+                                                       Report.SymbolRelatedToPreviousError (a.Location, a.GetSignatureForError ());
                                                        Report.Warning (1616, 1, "Option `{0}' overrides attribute `{1}' given in a source file or added module",
                                                                        "keycontainer", "System.Reflection.AssemblyKeyNameAttribute");
                                                } else {
index 9ff1d96690d07eb73a845ff1da331111abb318f7..4b5aa3e7db40e1828e05ed52118f1c8153aa82b0 100644 (file)
@@ -75,7 +75,7 @@ namespace Mono.CSharp {
                        ArrayList results = new ArrayList ();
 
                        AppendResults (results, Prefix, Evaluator.GetVarNames ());
-                       AppendResults (results, Prefix, ec.TypeContainer.NamespaceEntry.CompletionGetTypesStartingWith (ec.TypeContainer, Prefix));
+                       AppendResults (results, Prefix, ec.CurrentTypeDefinition.NamespaceEntry.CompletionGetTypesStartingWith (Prefix));
                        AppendResults (results, Prefix, Evaluator.GetUsingList ());
                        
                        throw new CompletionResult (Prefix, (string []) results.ToArray (typeof (string)));
@@ -172,7 +172,7 @@ namespace Mono.CSharp {
                                CompletionSimpleName.AppendResults (
                                        results,
                                        partial_name, 
-                                       ec.TypeContainer.NamespaceEntry.CompletionGetTypesStartingWith (ec.TypeContainer, namespaced_partial));
+                                       ec.CurrentTypeDefinition.NamespaceEntry.CompletionGetTypesStartingWith (namespaced_partial));
                        } else {
                                MemberInfo [] result = expr_type.FindMembers (
                                        MemberTypes.All, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public,
index dc5d1b19f5f5c1704672482e8f896d6aa6b563f6..882e5968d8b9e346c6d337202dffe32e0404dad6 100644 (file)
@@ -197,10 +197,16 @@ namespace Mono.CSharp {
                        in_transit = true;
                        // TODO: IResolveContext here
                        EmitContext ec = new EmitContext (
-                               this, Parent, Location, null, MemberType, ModFlags);
-                       ec.InEnumContext = this is EnumMember;
-                       ec.IsAnonymousMethodAllowed = false;
-                       value = DoResolveValue (ec);
+                               this, Parent, null, MemberType);
+
+                       EmitContext.Options opt = EmitContext.Options.ConstantScope;
+                       if (this is EnumMember)
+                               opt |= EmitContext.Options.EnumScope;
+
+                       using (ec.Set (opt)) {
+                               value = DoResolveValue (ec);
+                       }
+
                        in_transit = false;
                        resolved = true;
                        return value != null;
index 3cc2bb672dfcc5beaf8f771e731a90bed4332c6a..23955ffbd0dbbc0d00405766ba592b566c48f2c0 100644 (file)
@@ -1789,7 +1789,7 @@ namespace Mono.CSharp {
                        // Use string.Empty for both literals and constants even if
                        // it's not allowed at language level
                        //
-                       if (Value.Length == 0 && RootContext.Optimize && ec.TypeContainer.TypeBuilder != TypeManager.string_type) {                     
+                       if (Value.Length == 0 && RootContext.Optimize && !TypeManager.IsEqual (ec.CurrentType, TypeManager.string_type)) {
                                if (TypeManager.string_empty == null)
                                        TypeManager.string_empty = TypeManager.GetPredefinedField (TypeManager.string_type, "Empty", loc);
 
index 8aef3c2e88db25a0b4e21029ceab225f40cd60f2..bd3600475ceb822615bb1ccd92a810cce27df12f 100644 (file)
@@ -635,7 +635,7 @@ global_attributes
                if ($1 != null) {
                        Attributes attrs = (Attributes)$1;
                        if (global_attrs_enabled) {
-                               CodeGen.Assembly.AddAttributes (attrs.Attrs);
+                               CodeGen.Assembly.AddAttributes (attrs.Attrs, current_namespace);
                        } else {
                                foreach (Attribute a in attrs.Attrs) {
                                        Report.Error (1730, a.Location, "Assembly and module attributes must precede all other elements except using clauses and extern alias declarations");
@@ -671,7 +671,7 @@ attribute_sections
                                        current_container.Module.AddAttributes (sect);
                                        $$ = null;
                                } else if (current_attr_target != null && current_attr_target.Length > 0) {
-                                       CodeGen.Assembly.AddAttributes (sect);
+                                       CodeGen.Assembly.AddAttributes (sect, current_namespace);
                                        $$ = null;
                                } else {
                                        $$ = new Attributes (sect);
@@ -702,7 +702,7 @@ attribute_sections
                                        current_container.Module.AddAttributes (sect);
                                        $$ = null;
                                } else if (current_attr_target == "assembly") {
-                                       CodeGen.Assembly.AddAttributes (sect);
+                                       CodeGen.Assembly.AddAttributes (sect, current_namespace);
                                        $$ = null;
                                } else {
                                        if (attrs == null)
@@ -791,19 +791,16 @@ attribute
                }
 
                Arguments [] arguments = (Arguments []) $3;
-               MemberName left = mname.Left;
-               string identifier = mname.Name;
-
-               Expression left_expr = left == null ? null : left.GetTypeExpression ();
+               ATypeNameExpression expr = mname.GetTypeExpression ();
 
                if (current_attr_target == String.Empty)
                        $$ = null;
                else if (global_attrs_enabled && (current_attr_target == "assembly" || current_attr_target == "module"))
                        // FIXME: supply "nameEscaped" parameter here.
                        $$ = new GlobalAttribute (current_namespace, current_attr_target,
-                                                 left_expr, identifier, arguments, mname.Location, lexer.IsEscapedIdentifier (mname.Location));
+                                                 expr, arguments, mname.Location, lexer.IsEscapedIdentifier (mname.Location));
                else
-                       $$ = new Attribute (current_attr_target, left_expr, identifier, arguments, mname.Location, lexer.IsEscapedIdentifier (mname.Location));
+                       $$ = new Attribute (current_attr_target, expr, arguments, mname.Location, lexer.IsEscapedIdentifier (mname.Location));
          }
        ;
 
index dcfea8878bb40654fc0fe038383c4d853ff821c5..d5f99de68ff996e9ee38952b3cfe712db41ff214 100644 (file)
@@ -317,11 +317,11 @@ namespace Mono.CSharp {
                internal Flags caching_flags;
 
                public MemberCore (DeclSpace parent, MemberName name, Attributes attrs)
-                       : base (attrs)
                {
                        this.Parent = parent;
                        member_name = name;
                        caching_flags = Flags.Obsolete_Undetected | Flags.ClsCompliance_Undetected | Flags.HasCompliantAttribute_Undetected | Flags.Excluded_Undetected;
+                       AddAttributes (attrs, this);
                }
 
                protected virtual void SetMemberName (MemberName new_name)
@@ -670,6 +670,21 @@ namespace Mono.CSharp {
                        return true;
                }
 
+               public virtual ExtensionMethodGroupExpr LookupExtensionMethod (Type extensionType, string name, Location loc)
+               {
+                       return Parent.LookupExtensionMethod (extensionType, name, loc);
+               }
+
+               public virtual FullNamedExpression LookupNamespaceAlias (string name)
+               {
+                       return Parent.NamespaceEntry.LookupNamespaceAlias (name);
+               }
+
+               public virtual FullNamedExpression LookupNamespaceOrType (string name, Location loc, bool ignore_cs0104)
+               {
+                       return Parent.LookupNamespaceOrType (name, loc, ignore_cs0104);
+               }
+
                /// <summary>
                /// Goes through class hierarchy and gets value of first found CLSCompliantAttribute.
                /// If no is attribute exists then assembly CLSCompliantAttribute is returned.
@@ -803,11 +818,19 @@ namespace Mono.CSharp {
                        }
                }
 
-               public override IResolveContext ResolveContext {
-                       get { return this; }
+               #region IResolveContext Members
+
+               public virtual Type CurrentType {
+                       get { return Parent.CurrentType; }
                }
 
-               #region IResolveContext Members
+               public virtual TypeContainer CurrentTypeDefinition {
+                       get { return Parent.CurrentTypeDefinition; }
+               }
+
+               public virtual TypeParameter[] CurrentTypeParameters {
+                       get { return null; }
+               }
 
                public DeclSpace DeclContainer {
                        get { return Parent; }
@@ -835,6 +858,10 @@ namespace Mono.CSharp {
                        }
                }
 
+               public bool IsStatic {
+                       get { return (ModFlags & Modifiers.STATIC) != 0; }
+               }
+
                #endregion
        }
 
@@ -858,7 +885,7 @@ namespace Mono.CSharp {
                ///   currently defining.  We need to lookup members on this
                ///   instead of the TypeBuilder.
                /// </summary>
-               public Type CurrentType;
+               protected Type currentType;
 
                //
                // This is the namespace in which this typecontainer
@@ -1074,6 +1101,9 @@ namespace Mono.CSharp {
                        if (TypeManager.HasElementType (check_type))
                                return CheckAccessLevel (TypeManager.GetElementType (check_type));
 
+                       if (TypeManager.IsGenericParameter (check_type))
+                               return true;
+
                        TypeAttributes check_attr = check_type.Attributes & TypeAttributes.VisibilityMask;
 
                        switch (check_attr){
@@ -1189,11 +1219,6 @@ namespace Mono.CSharp {
                        return null;
                }
 
-               public virtual ExtensionMethodGroupExpr LookupExtensionMethod (Type extensionType, string name, Location loc)
-               {
-                       return null;
-               }
-
                //
                // Public function used to locate types.
                //
@@ -1201,20 +1226,31 @@ namespace Mono.CSharp {
                //
                // Returns: Type or null if they type can not be found.
                //
-               public FullNamedExpression LookupNamespaceOrType (string name, Location loc, bool ignore_cs0104)
+               public override FullNamedExpression LookupNamespaceOrType (string name, Location loc, bool ignore_cs0104)
                {
                        if (Cache.Contains (name))
                                return (FullNamedExpression) Cache [name];
 
-                       FullNamedExpression e;
+                       FullNamedExpression e = null;
                        int errors = Report.Errors;
-                       Type t = LookupNestedTypeInHierarchy (name);
-                       if (t != null)
-                               e = new TypeExpression (t, Location.Null);
-                       else if (Parent != null)
-                               e = Parent.LookupNamespaceOrType (name, loc, ignore_cs0104);
-                       else
-                               e = NamespaceEntry.LookupNamespaceOrType (this, name, loc, ignore_cs0104);
+
+                       TypeParameter[] tp = CurrentTypeParameters;
+                       if (tp != null) {
+                               TypeParameter tparam = TypeParameter.FindTypeParameter (tp, name);
+                               if (tparam != null)
+                                       e = new TypeParameterExpr (tparam, Location.Null);
+                       }
+
+                       if (e == null) {
+                               Type t = LookupNestedTypeInHierarchy (name);
+
+                               if (t != null)
+                                       e = new TypeExpression (t, Location.Null);
+                               else if (Parent != null)
+                                       e = Parent.LookupNamespaceOrType (name, loc, ignore_cs0104);
+                               else
+                                       e = NamespaceEntry.LookupNamespaceOrType (name, loc, ignore_cs0104);
+                       }
 
                        if (errors == Report.Errors)
                                Cache [name] = e;
@@ -1268,7 +1304,7 @@ namespace Mono.CSharp {
                        ArrayList list = new ArrayList ();
                        if (the_parent != null && the_parent.IsGeneric) {
                                // FIXME: move generics info out of DeclSpace
-                               TypeParameter[] parent_params = the_parent.PartialContainer.TypeParameters;
+                               TypeParameter[] parent_params = the_parent.TypeParameters;
                                list.AddRange (parent_params);
                        }
  
@@ -1276,8 +1312,8 @@ namespace Mono.CSharp {
                        for (int i = 0; i < count; i++) {
                                TypeParameter param = type_params [i];
                                list.Add (param);
-                               if (Parent.IsGeneric) {
-                                       foreach (TypeParameter tp in Parent.PartialContainer.CurrentTypeParameters) {
+                               if (Parent.CurrentTypeParameters != null) {
+                                       foreach (TypeParameter tp in Parent.CurrentTypeParameters) {
                                                if (tp.Name != param.Name)                              
                                                        continue;
 
@@ -1367,17 +1403,12 @@ namespace Mono.CSharp {
                        }
                }
 
-               public TypeParameter[] CurrentTypeParameters {
-                       get {
-                               if (!IsGeneric)
-                                       throw new InvalidOperationException ();
-
-                               // TODO: Something is seriously broken here
-                               if (type_params == null)
-                                       return new TypeParameter [0];
+               public override Type CurrentType {
+                       get { return currentType != null ? currentType : TypeBuilder; }
+               }
 
-                               return type_params;
-                       }
+               public override TypeContainer CurrentTypeDefinition {
+                       get { return PartialContainer; }
                }
 
                public int CountTypeParameters {
@@ -1386,28 +1417,6 @@ namespace Mono.CSharp {
                        }
                }
 
-               public TypeParameterExpr LookupGeneric (string name, Location loc)
-               {
-                       if (!IsGeneric)
-                               return null;
-
-                       TypeParameter [] current_params;
-                       if (this is TypeContainer)
-                               current_params = PartialContainer.CurrentTypeParameters;
-                       else
-                               current_params = CurrentTypeParameters;
-
-                       foreach (TypeParameter type_param in current_params) {
-                               if (type_param.Name == name)
-                                       return new TypeParameterExpr (type_param, loc);
-                       }
-
-                       if (Parent != null)
-                               return Parent.LookupGeneric (name, loc);
-
-                       return null;
-               }
-
                // Used for error reporting only
                public virtual Type LookupAnyGeneric (string typeName)
                {
index e7b65cf5aa8a7b9f46f6bd72cbd2e709d98b4577..783a8d415b17d8ca2cff845a8e9119980eec0f9a 100644 (file)
@@ -80,6 +80,12 @@ namespace Mono.CSharp {
                        base.ApplyAttributeBuilder (a, cb, pa);
                }
 
+               public override TypeParameter[] CurrentTypeParameters {
+                       get {
+                               return base.type_params;
+                       }
+               }
+
                public override TypeBuilder DefineType ()
                {
                        if (TypeBuilder != null)
@@ -112,13 +118,17 @@ namespace Mono.CSharp {
                                GenericTypeParameterBuilder[] gen_params;
                                gen_params = TypeBuilder.DefineGenericParameters (param_names);
 
-                               int offset = CountTypeParameters - CurrentTypeParameters.Length;
+                               int offset = CountTypeParameters;
+                               if (CurrentTypeParameters != null)
+                                       offset -= CurrentTypeParameters.Length;
                                for (int i = offset; i < gen_params.Length; i++)
                                        CurrentTypeParameters [i - offset].Define (gen_params [i]);
 
-                               foreach (TypeParameter type_param in CurrentTypeParameters) {
-                                       if (!type_param.Resolve (this))
-                                               return null;
+                               if (CurrentTypeParameters != null) {
+                                       foreach (TypeParameter type_param in CurrentTypeParameters) {
+                                               if (!type_param.Resolve (this))
+                                                       return null;
+                                       }
                                }
 
                                Expression current = new SimpleName (
@@ -127,7 +137,7 @@ namespace Mono.CSharp {
                                if (current == null)
                                        return null;
 
-                               CurrentType = current.Type;
+                               currentType = current.Type;
                        }
 #endif
 
@@ -500,7 +510,7 @@ namespace Mono.CSharp {
                        else
                                arg_count = args.Count;
 
-                       MethodBase mb = GetInvokeMethod (ec.ContainerType, delegate_type);
+                       MethodBase mb = GetInvokeMethod (ec.CurrentType, delegate_type);
                        MethodGroupExpr me = new MethodGroupExpr (new MemberInfo [] { mb }, delegate_type, loc);
                        
                        AParametersCollection pd = TypeManager.GetParameterData (mb);
@@ -661,9 +671,9 @@ namespace Mono.CSharp {
 
                public override Expression DoResolve (EmitContext ec)
                {
-                       constructor_method = Delegate.GetConstructor (ec.ContainerType, type);
+                       constructor_method = Delegate.GetConstructor (ec.CurrentType, type);
 
-                       MethodInfo invoke_method = Delegate.GetInvokeMethod (ec.ContainerType, type);
+                       MethodInfo invoke_method = Delegate.GetInvokeMethod (ec.CurrentType, type);
                        method_group.DelegateType = type;
                        method_group.CustomErrorHandler = this;
 
@@ -755,7 +765,7 @@ namespace Mono.CSharp {
 
                void Error_ConversionFailed (EmitContext ec, MethodBase method, Expression return_type)
                {
-                       MethodInfo invoke_method = Delegate.GetInvokeMethod (ec.ContainerType, type);
+                       MethodInfo invoke_method = Delegate.GetInvokeMethod (ec.CurrentType, type);
                        string member_name = delegate_instance_expression != null ?
                                Delegate.FullDelegateDesc (method) :
                                TypeManager.GetFullNameSignature (method);
@@ -890,7 +900,7 @@ namespace Mono.CSharp {
                                //
                                delegate_instance_expression = e;
                                method_group = new MethodGroupExpr (new MemberInfo [] { 
-                                       Delegate.GetInvokeMethod (ec.ContainerType, e.Type) }, e.Type, loc);
+                                       Delegate.GetInvokeMethod (ec.CurrentType, e.Type) }, e.Type, loc);
                        }
 
                        return base.DoResolve (ec);
@@ -937,7 +947,7 @@ namespace Mono.CSharp {
                        if (!Delegate.VerifyApplicability (ec, del_type, ref Arguments, loc))
                                return null;
 
-                       method = Delegate.GetInvokeMethod (ec.ContainerType, del_type);
+                       method = Delegate.GetInvokeMethod (ec.CurrentType, del_type);
                        type = TypeManager.TypeToCoreType (method.ReturnType);
                        eclass = ExprClass.Value;
                        
index dd7855a64fcf18bbb32782165c9948a0f7c9eca4..41a8e6975851f33136022b69da1899392d71f942 100644 (file)
@@ -262,7 +262,7 @@ namespace Mono.CSharp
                        MemberAccess binder = GetBinderNamespace (loc);
 
                        binder_args.Add (new Argument (new StringLiteral (name, loc)));
-                       binder_args.Add (new Argument (new TypeOf (new TypeExpression (ec.ContainerType, loc), loc)));
+                       binder_args.Add (new Argument (new TypeOf (new TypeExpression (ec.CurrentType, loc), loc)));
 
                        return new New (new MemberAccess (binder, "CSharpIsEventBinder", loc), binder_args, loc);
                }
@@ -298,7 +298,7 @@ namespace Mono.CSharp
                        binder_args.Add (new Argument (new TypeOf (new TypeExpression (type, loc), loc)));
                        binder_args.Add (new Argument (new MemberAccess (new MemberAccess (binder, "CSharpConversionKind", loc),
                                is_explicit ? "ExplicitConversion" : "ImplicitConversion", loc)));
-                       binder_args.Add (new Argument (new BoolLiteral (ec.CheckState, loc)));
+                       binder_args.Add (new Argument (new BoolLiteral (ec.HasSet (EmitContext.Options.CheckedScope), loc)));
                                
                        return new New (new MemberAccess (binder, "CSharpConvertBinder", loc), binder_args, loc);
                }
@@ -320,7 +320,7 @@ namespace Mono.CSharp
                        Arguments binder_args = new Arguments (2);
                        MemberAccess binder = GetBinderNamespace (loc);
 
-                       binder_args.Add (new Argument (new TypeOf (new TypeExpression (ec.ContainerType, loc), loc)));
+                       binder_args.Add (new Argument (new TypeOf (new TypeExpression (ec.CurrentType, loc), loc)));
                        binder_args.Add (new Argument (new ImplicitlyTypedArrayCreation ("[]", args.CreateDynamicBinderArguments (), loc)));
 
                        return new New (new MemberAccess (binder, isSet ? "CSharpSetIndexBinder" : "CSharpGetIndexBinder", loc), binder_args, loc);
@@ -378,7 +378,7 @@ namespace Mono.CSharp
                        if (is_member_access)
                                binder_args.Add (new Argument (new StringLiteral (member.Name, member.Location)));
 
-                       binder_args.Add (new Argument (new TypeOf (new TypeExpression (ec.ContainerType, loc), loc)));
+                       binder_args.Add (new Argument (new TypeOf (new TypeExpression (ec.CurrentType, loc), loc)));
 
                        if (member != null && member.HasTypeArguments) {
                                TypeArguments ta = member.TypeArguments;
@@ -427,7 +427,7 @@ namespace Mono.CSharp
                        MemberAccess binder = GetBinderNamespace (loc);
 
                        binder_args.Add (new Argument (new StringLiteral (name, loc)));
-                       binder_args.Add (new Argument (new TypeOf (new TypeExpression (ec.ContainerType, loc), loc)));
+                       binder_args.Add (new Argument (new TypeOf (new TypeExpression (ec.CurrentType, loc), loc)));
                        binder_args.Add (new Argument (new ImplicitlyTypedArrayCreation ("[]", args.CreateDynamicBinderArguments (), loc)));
 
                        return new New (new MemberAccess (binder, isSet ? "CSharpSetMemberBinder" : "CSharpGetMemberBinder", loc), binder_args, loc);
@@ -471,7 +471,7 @@ namespace Mono.CSharp
                        MemberAccess binder = GetBinderNamespace (loc);
 
                        binder_args.Add (new Argument (new MemberAccess (new MemberAccess (sle, "ExpressionType", loc), name, loc)));
-                       binder_args.Add (new Argument (new BoolLiteral (ec.CheckState, loc)));
+                       binder_args.Add (new Argument (new BoolLiteral (ec.HasSet (EmitContext.Options.CheckedScope), loc)));
                        binder_args.Add (new Argument (new ImplicitlyTypedArrayCreation ("[]", args.CreateDynamicBinderArguments (), loc)));
 
                        return new New (new MemberAccess (binder, "CSharpUnaryOperationBinder", loc), binder_args, loc);
index 05bca73325040065f303865fa3822936dde4a5db..400d1f41056ea43d69328672ff281bc2caceb94c 100644 (file)
@@ -284,9 +284,15 @@ namespace Mono.CSharp {
 
                        GenericTypeExpr ct = te as GenericTypeExpr;
                        if (ct != null) {
-                               // Skip constrains check for overrides and explicit implementations
-                               // TODO: they should use different overload
-                               GenericMethod gm = ec.GenericDeclContainer as GenericMethod;
+                               //
+                               // TODO: Constrained type parameters check for parameters of generic method overrides is broken
+                               // There are 2 solutions.
+                               // 1, Skip this check completely when we are in override/explicit impl scope
+                               // 2, Copy type parameters constraints from base implementation and pass (they have to be emitted anyway)
+                               //
+                               MemberCore gm = ec as GenericMethod;
+                               if (gm == null)
+                                       gm = ec as Method;
                                if (gm != null && ((gm.ModFlags & Modifiers.OVERRIDE) != 0 || gm.MemberName.Left != null)) {
                                        te.loc = loc;
                                        return te;
@@ -825,13 +831,13 @@ namespace Mono.CSharp {
                        Expression e;
 
                        int errors = Report.Errors;
-                       e = MemberLookup (ec.ContainerType, qualifier_type, queried_type, name, mt, bf, loc);
+                       e = MemberLookup (ec.CurrentType, qualifier_type, queried_type, name, mt, bf, loc);
 
                        if (e != null || errors != Report.Errors)
                                return e;
 
                        // No errors were reported by MemberLookup, but there was an error.
-                       return Error_MemberLookupFailed (ec.ContainerType, qualifier_type, queried_type,
+                       return Error_MemberLookupFailed (ec.CurrentType, qualifier_type, queried_type,
                                        name, null, mt, bf);
                }
 
@@ -863,7 +869,7 @@ namespace Mono.CSharp {
                                                        // Although a derived class can access protected members of
                                                        // its base class it cannot do so through an instance of the
                                                        // base class (CS1540).  If the qualifier_type is a base of the
-                                                       // ec.ContainerType and the lookup succeeds with the latter one,
+                                                       // ec.CurrentType and the lookup succeeds with the latter one,
                                                        // then we are in this situation.
                                                        Error_CannotAccessProtected (loc, mi, qualifier_type, container_type);
                                                } else {
@@ -950,7 +956,7 @@ namespace Mono.CSharp {
                {
                        MethodGroupExpr operator_group;
                        string mname = Operator.GetMetadataName (is_true ? Operator.OpType.True : Operator.OpType.False);
-                       operator_group = MethodLookup (ec.ContainerType, e.Type, mname, loc) as MethodGroupExpr;
+                       operator_group = MethodLookup (ec.CurrentType, e.Type, mname, loc) as MethodGroupExpr;
                        if (operator_group == null)
                                return null;
 
@@ -1034,16 +1040,18 @@ namespace Mono.CSharp {
                /// <summary>
                ///   Reports that we were expecting `expr' to be of class `expected'
                /// </summary>
-               public void Error_UnexpectedKind (DeclSpace ds, string expected, Location loc)
+               public void Error_UnexpectedKind (MemberCore mc, string expected, Location loc)
                {
-                       Error_UnexpectedKind (ds, expected, ExprClassName, loc);
+                       Error_UnexpectedKind (mc, expected, ExprClassName, loc);
                }
 
-               public void Error_UnexpectedKind (DeclSpace ds, string expected, string was, Location loc)
+               public void Error_UnexpectedKind (MemberCore mc, string expected, string was, Location loc)
                {
-                       string name = GetSignatureForError ();
-                       if (ds != null)
-                               name = ds.GetSignatureForError () + '.' + name;
+                       string name;
+                       if (mc != null)
+                               name = mc.GetSignatureForError ();
+                       else
+                               name = GetSignatureForError ();
 
                        Report.Error (118, loc, "`{0}' is a `{1}' but a `{2}' was expected",
                              name, was, expected);
@@ -1224,7 +1232,7 @@ namespace Mono.CSharp {
 
                        Expression converted;
                        
-                       using (ec.With (EmitContext.Flags.CheckState, true)) {
+                       using (ec.Set (EmitContext.Options.CheckedScope)) {
                                converted = Convert.ImplicitConversion (ec, source, TypeManager.int32_type, source.loc);
                                if (converted == null)
                                        converted = Convert.ImplicitConversion (ec, source, TypeManager.uint32_type, source.loc);
@@ -1395,7 +1403,7 @@ namespace Mono.CSharp {
                        if (type.IsPointer || child.Type.IsPointer)
                                Error_PointerInsideExpressionTree ();
 
-                       return CreateExpressionFactoryCall (ec.CheckState ? "ConvertChecked" : "Convert", args);
+                       return CreateExpressionFactoryCall (ec.HasSet (EmitContext.Options.CheckedScope) ? "ConvertChecked" : "Convert", args);
                }
 
                public override Expression DoResolve (EmitContext ec)
@@ -1942,7 +1950,7 @@ namespace Mono.CSharp {
                        
                        base.Emit (ec);
 
-                       if (ec.CheckState){
+                       if (ec.HasSet (EmitContext.Options.CheckedScope)){
                                switch (mode){
                                case Mode.I1_U1: ig.Emit (OpCodes.Conv_Ovf_U1); break;
                                case Mode.I1_U2: ig.Emit (OpCodes.Conv_Ovf_U2); break;
@@ -2330,18 +2338,18 @@ namespace Mono.CSharp {
        //
        public abstract class ATypeNameExpression : FullNamedExpression
        {
-               public readonly string Name;
+               string name;
                protected TypeArguments targs;
 
                protected ATypeNameExpression (string name, Location l)
                {
-                       Name = name;
+                       this.name = name;
                        loc = l;
                }
 
                protected ATypeNameExpression (string name, TypeArguments targs, Location l)
                {
-                       Name = name;
+                       this.name = name;
                        this.targs = targs;
                        loc = l;
                }
@@ -2374,6 +2382,15 @@ namespace Mono.CSharp {
                        return Name;
                }
 
+               public string Name {
+                       get {
+                               return name;
+                       }
+                       set {
+                               name = value;
+                       }
+               }
+
                public TypeArguments TypeArguments {
                        get {
                                return targs;
@@ -2441,7 +2458,7 @@ namespace Mono.CSharp {
 
                public static void Error_ObjectRefRequired (EmitContext ec, Location l, string name)
                {
-                       if (ec.IsInFieldInitializer)
+                       if (ec.HasSet (EmitContext.Options.FieldInitializerScope))
                                Report.Error (236, l,
                                        "A field initializer cannot reference the nonstatic field, method, or property `{0}'",
                                        name);
@@ -2451,11 +2468,11 @@ namespace Mono.CSharp {
                                        name);
                }
 
-               public bool IdenticalNameAndTypeName (EmitContext ec, Expression resolved_to, Location loc)
+               public bool IdenticalNameAndTypeName (IResolveContext mc, Expression resolved_to, Location loc)
                {
                        return resolved_to != null && resolved_to.Type != null && 
                                resolved_to.Type.Name == Name &&
-                               (ec.DeclContainer.LookupNamespaceOrType (Name, loc, /* ignore_cs0104 = */ true) != null);
+                               (mc.LookupNamespaceOrType (Name, loc, /* ignore_cs0104 = */ true) != null);
                }
 
                public override Expression DoResolve (EmitContext ec)
@@ -2491,7 +2508,10 @@ namespace Mono.CSharp {
                        if (!TypeManager.IsGenericTypeDefinition (t) && !TypeManager.IsGenericType (t))
                                return null;
 
-                       DeclSpace ds = ec.DeclContainer;
+                       if (ec.CurrentType == null)
+                               return null;
+
+                       DeclSpace ds = ec.CurrentTypeDefinition;
                        while (ds != null && !IsNestedChild (t, ds.TypeBuilder))
                                ds = ds.Parent;
 
@@ -2520,12 +2540,8 @@ namespace Mono.CSharp {
 
                public override FullNamedExpression ResolveAsTypeStep (IResolveContext ec, bool silent)
                {
-                       FullNamedExpression fne = ec.GenericDeclContainer.LookupGeneric (Name, loc);
-                       if (fne != null)
-                               return fne.ResolveAsTypeStep (ec, silent);
-
                        int errors = Report.Errors;
-                       fne = ec.DeclContainer.LookupNamespaceOrType (Name, loc, /*ignore_cs0104=*/ false);
+                       FullNamedExpression fne = ec.LookupNamespaceOrType (Name, loc, /*ignore_cs0104=*/ false);
 
                        if (fne != null) {
                                if (fne.Type == null)
@@ -2555,31 +2571,37 @@ namespace Mono.CSharp {
 
                protected virtual void Error_TypeOrNamespaceNotFound (IResolveContext ec)
                {
-                       MemberCore mc = ec.DeclContainer.GetDefinition (Name);
-                       if (mc != null) {
-                               Error_UnexpectedKind (ec.DeclContainer, "type", GetMemberType (mc), loc);
-                               return;
-                       }
+                       if (ec.CurrentType != null) {
+                               if (ec.CurrentTypeDefinition != null) {
+                                       MemberCore mc = ec.CurrentTypeDefinition.GetDefinition (Name);
+                                       if (mc != null) {
+                                               Error_UnexpectedKind (mc, "type", GetMemberType (mc), loc);
+                                               return;
+                                       }
+                               }
 
-                       string ns = ec.DeclContainer.NamespaceEntry.NS.Name;
-                       string fullname = (ns.Length > 0) ? ns + "." + Name : Name;
-                       foreach (Assembly a in GlobalRootNamespace.Instance.Assemblies) {
-                               Type type = a.GetType (fullname);
-                               if (type != null) {
-                                       Report.SymbolRelatedToPreviousError (type);
-                                       Expression.ErrorIsInaccesible (loc, TypeManager.CSharpName (type));
-                                       return;
+                               string ns = ec.CurrentType.Namespace;
+                               string fullname = (ns.Length > 0) ? ns + "." + Name : Name;
+                               foreach (Assembly a in GlobalRootNamespace.Instance.Assemblies) {
+                                       Type type = a.GetType (fullname);
+                                       if (type != null) {
+                                               Report.SymbolRelatedToPreviousError (type);
+                                               Expression.ErrorIsInaccesible (loc, TypeManager.CSharpName (type));
+                                               return;
+                                       }
                                }
-                       }
 
-                       Type t = ec.DeclContainer.LookupAnyGeneric (Name);
-                       if (t != null) {
-                               Namespace.Error_InvalidNumberOfTypeArguments (t, loc);
-                               return;
+                               if (ec.CurrentTypeDefinition != null) {
+                                       Type t = ec.CurrentTypeDefinition.LookupAnyGeneric (Name);
+                                       if (t != null) {
+                                               Namespace.Error_InvalidNumberOfTypeArguments (t, loc);
+                                               return;
+                                       }
+                               }
                        }
 
                        if (targs != null) {
-                               FullNamedExpression retval = ec.DeclContainer.LookupNamespaceOrType (SimpleName.RemoveGenericArity (Name), loc, true);
+                               FullNamedExpression retval = ec.LookupNamespaceOrType (SimpleName.RemoveGenericArity (Name), loc, true);
                                if (retval != null) {
                                        Namespace.Error_TypeArgumentsCannotBeUsed (retval, loc);
                                        return;
@@ -2681,12 +2703,8 @@ namespace Mono.CSharp {
 
                        Type almost_matched_type = null;
                        ArrayList almost_matched = null;
-                       for (DeclSpace lookup_ds = ec.DeclContainer; lookup_ds != null; lookup_ds = lookup_ds.Parent) {
-                               // either RootDeclSpace or GenericMethod
-                               if (lookup_ds.TypeBuilder == null)
-                                       continue;
-
-                               e = MemberLookup (ec.ContainerType, lookup_ds.TypeBuilder, Name, loc);
+                       for (Type lookup_ds = ec.CurrentType; lookup_ds != null; lookup_ds = lookup_ds.DeclaringType) {
+                               e = MemberLookup (ec.CurrentType, lookup_ds, Name, loc);
                                if (e != null) {
                                        PropertyExpr pe = e as PropertyExpr;
                                        if (pe != null) {
@@ -2694,10 +2712,10 @@ namespace Mono.CSharp {
 
                                                // since TypeManager.MemberLookup doesn't know if we're doing a lvalue access or not,
                                                // it doesn't know which accessor to check permissions against
-                                               if (param.IsEmpty && pe.IsAccessibleFrom (ec.ContainerType, right_side != null))
+                                               if (param.IsEmpty && pe.IsAccessibleFrom (ec.CurrentType, right_side != null))
                                                        break;
                                        } else if (e is EventExpr) {
-                                               if (((EventExpr) e).IsAccessibleFrom (ec.ContainerType))
+                                               if (((EventExpr) e).IsAccessibleFrom (ec.CurrentType))
                                                        break;
                                        } else if (targs != null && e is TypeExpression) {
                                                e = new GenericTypeExpr (e.Type, targs, loc).ResolveAsTypeStep (ec, false);
@@ -2709,14 +2727,14 @@ namespace Mono.CSharp {
                                }
 
                                if (almost_matched == null && almost_matched_members.Count > 0) {
-                                       almost_matched_type = lookup_ds.TypeBuilder;
+                                       almost_matched_type = lookup_ds;
                                        almost_matched = (ArrayList) almost_matched_members.Clone ();
                                }
                        }
 
                        if (e == null) {
                                if (almost_matched == null && almost_matched_members.Count > 0) {
-                                       almost_matched_type = ec.ContainerType;
+                                       almost_matched_type = ec.CurrentType;
                                        almost_matched = (ArrayList) almost_matched_members.Clone ();
                                }
                                e = ResolveAsTypeStep (ec, true);
@@ -2745,9 +2763,11 @@ namespace Mono.CSharp {
                                if (almost_matched != null)
                                        almost_matched_members = almost_matched;
                                if (almost_matched_type == null)
-                                       almost_matched_type = ec.ContainerType;
-                               return Error_MemberLookupFailed (ec.ContainerType, null, almost_matched_type, Name,
-                                       ec.DeclContainer.Name, AllMemberTypes, AllBindingFlags);
+                                       almost_matched_type = ec.CurrentType;
+
+                               string type_name = ec.ResolveContext.CurrentType == null ? null : ec.ResolveContext.CurrentType.Name;
+                               return Error_MemberLookupFailed (ec.CurrentType, null, almost_matched_type, Name,
+                                       type_name, AllMemberTypes, AllBindingFlags);
                        }
 
                        if (e is MemberExpr) {
@@ -2755,7 +2775,7 @@ namespace Mono.CSharp {
 
                                Expression left;
                                if (me.IsInstance) {
-                                       if (ec.IsStatic || ec.IsInFieldInitializer) {
+                                       if (ec.IsStatic || ec.HasAny (EmitContext.Options.FieldInitializerScope | EmitContext.Options.BaseInitializer | EmitContext.Options.ConstantScope)) {
                                                //
                                                // Note that an MemberExpr can be both IsInstance and IsStatic.
                                                // An unresolved MethodGroupExpr can contain both kinds of methods
@@ -2777,7 +2797,7 @@ namespace Mono.CSharp {
                                                left = ec.GetThis (loc);
                                        }
                                } else {
-                                       left = new TypeExpression (ec.ContainerType, loc);
+                                       left = new TypeExpression (ec.CurrentType, loc);
                                }
 
                                me = me.ResolveMemberAccess (ec, left, loc, null);
@@ -2968,7 +2988,7 @@ namespace Mono.CSharp {
                        //
                        if (type == null) {
                                Namespace ns = GlobalRootNamespace.Instance.GetNamespace (ns_name, false);
-                               FullNamedExpression fne = ns.Lookup (null, name, loc);
+                               FullNamedExpression fne = ns.Lookup (name, loc);
                                if (fne != null)
                                        type = fne.Type;
                        }
@@ -3200,7 +3220,7 @@ namespace Mono.CSharp {
                                return null;
 
                        // Search continues
-                       ExtensionMethodGroupExpr e = ns.LookupExtensionMethod (type, null, Name, loc);
+                       ExtensionMethodGroupExpr e = ns.LookupExtensionMethod (type, Name, loc);
                        if (e == null)
                                return base.OverloadResolve (ec, ref arguments, false, loc);
 
@@ -4195,7 +4215,7 @@ namespace Mono.CSharp {
                                // not an extension method. We start extension methods lookup from here
                                //
                                if (InstanceExpression != null) {
-                                       ExtensionMethodGroupExpr ex_method_lookup = ec.TypeContainer.LookupExtensionMethod (type, Name, loc);
+                                       ExtensionMethodGroupExpr ex_method_lookup = ec.LookupExtensionMethod (type, Name, loc);
                                        if (ex_method_lookup != null) {
                                                ex_method_lookup.ExtensionExpression = InstanceExpression;
                                                ex_method_lookup.SetTypeArguments (type_arguments);
@@ -4242,13 +4262,13 @@ namespace Mono.CSharp {
                                                }
 
                                                if (has_inaccessible_candidates_only) {
-                                                       if (InstanceExpression != null && type != ec.ContainerType && TypeManager.IsNestedFamilyAccessible (ec.ContainerType, best_candidate.DeclaringType)) {
+                                                       if (InstanceExpression != null && type != ec.CurrentType && TypeManager.IsNestedFamilyAccessible (ec.CurrentType, best_candidate.DeclaringType)) {
                                                                // Although a derived class can access protected members of
                                                                // its base class it cannot do so through an instance of the
                                                                // base class (CS1540).  If the qualifier_type is a base of the
-                                                               // ec.ContainerType and the lookup succeeds with the latter one,
+                                                               // ec.CurrentType and the lookup succeeds with the latter one,
                                                                // then we are in this situation.
-                                                               Error_CannotAccessProtected (loc, best_candidate, queried_type, ec.ContainerType);
+                                                               Error_CannotAccessProtected (loc, best_candidate, queried_type, ec.CurrentType);
                                                        } else {
                                                                Report.SymbolRelatedToPreviousError (best_candidate);
                                                                ErrorIsInaccesible (loc, GetSignatureForError ());
@@ -4812,7 +4832,7 @@ namespace Mono.CSharp {
                                // "a.b" is initialized, not whether the whole struct "a" is initialized.
 
                                if (lvalue_instance) {
-                                       using (ec.With (EmitContext.Flags.DoFlowAnalysis, false)) {
+                                       using (ec.With (EmitContext.Options.DoFlowAnalysis, false)) {
                                                Expression right_side =
                                                        out_access ? EmptyExpression.LValueMemberOutAccess : EmptyExpression.LValueMemberAccess;
 
@@ -4829,7 +4849,7 @@ namespace Mono.CSharp {
                                if (InstanceExpression == null)
                                        return null;
 
-                               using (ec.Set (EmitContext.Flags.OmitStructFlowAnalysis)) {
+                               using (ec.Set (EmitContext.Options.OmitStructFlowAnalysis)) {
                                        InstanceExpression.CheckMarshalByRefAccess (ec);
                                }
                        }
@@ -4854,7 +4874,7 @@ namespace Mono.CSharp {
                        
                        if (fb != null) {
                                IFixedExpression fe = InstanceExpression as IFixedExpression;
-                               if (!ec.InFixedInitializer && (fe == null || !fe.IsFixed)) {
+                               if (!ec.HasSet (EmitContext.Options.FixedInitializerScope) && (fe == null || !fe.IsFixed)) {
                                        Report.Error (1666, loc, "You cannot use fixed size buffers contained in unfixed expressions. Try using the fixed statement");
                                }
 
@@ -4941,13 +4961,11 @@ namespace Mono.CSharp {
 
                        if (FieldInfo.IsInitOnly) {
                                // InitOnly fields can only be assigned in constructors or initializers
-                               if (!ec.IsInFieldInitializer && !ec.IsConstructor)
+                               if (!ec.HasAny (EmitContext.Options.FieldInitializerScope | EmitContext.Options.ConstructorScope))
                                        return Report_AssignToReadonly (right_side);
 
-                               if (ec.IsConstructor) {
-                                       Type ctype = ec.TypeContainer.CurrentType;
-                                       if (ctype == null)
-                                               ctype = ec.ContainerType;
+                               if (ec.HasSet (EmitContext.Options.ConstructorScope)) {
+                                       Type ctype = ec.CurrentType;
 
                                        // InitOnly fields cannot be assigned-to in a different constructor from their declaring type
                                        if (!TypeManager.IsEqual (ctype, FieldInfo.DeclaringType))
@@ -5052,7 +5070,7 @@ namespace Mono.CSharp {
 
                                // Optimization for build-in types
                                // TODO: Iterators don't set current container
-                               if (TypeManager.IsStruct (type) && type == ec.DeclContainer.TypeBuilder && ec.CurrentIterator == null) {
+                               if (TypeManager.IsStruct (type) && TypeManager.IsEqual (type, ec.ResolveContext.CurrentType) && ec.CurrentIterator == null) {
                                        LoadFromPtr (ig, type);
                                } else {
                                        IFixedBuffer ff = AttributeTester.GetFixedBuffer (FieldInfo);
@@ -5084,7 +5102,7 @@ namespace Mono.CSharp {
                        bool is_readonly = (fa & FieldAttributes.InitOnly) != 0;
                        ILGenerator ig = ec.ig;
 
-                       if (is_readonly && !ec.IsConstructor){
+                       if (is_readonly && !ec.HasSet (EmitContext.Options.ConstructorScope)){
                                Report_AssignToReadonly (source);
                                return;
                        }
@@ -5166,7 +5184,7 @@ namespace Mono.CSharp {
                        bool need_copy;
                        if (FieldInfo.IsInitOnly){
                                need_copy = true;
-                               if (ec.IsConstructor){
+                               if (ec.HasSet (EmitContext.Options.ConstructorScope)){
                                        if (FieldInfo.IsStatic){
                                                if (ec.IsStatic)
                                                        need_copy = false;
@@ -5396,11 +5414,11 @@ namespace Mono.CSharp {
                        InstanceExpression.CheckMarshalByRefAccess (ec);
 
                        if (must_do_cs1540_check && (InstanceExpression != EmptyExpression.Null) &&
-                           !TypeManager.IsInstantiationOfSameGenericType (InstanceExpression.Type, ec.ContainerType) &&
-                           !TypeManager.IsNestedChildOf (ec.ContainerType, InstanceExpression.Type) &&
-                           !TypeManager.IsSubclassOf (InstanceExpression.Type, ec.ContainerType)) {
+                           !TypeManager.IsInstantiationOfSameGenericType (InstanceExpression.Type, ec.CurrentType) &&
+                           !TypeManager.IsNestedChildOf (ec.CurrentType, InstanceExpression.Type) &&
+                           !TypeManager.IsSubclassOf (InstanceExpression.Type, ec.CurrentType)) {
                                Report.SymbolRelatedToPreviousError (PropertyInfo);
-                               Error_CannotAccessProtected (loc, PropertyInfo, InstanceExpression.Type, ec.ContainerType);
+                               Error_CannotAccessProtected (loc, PropertyInfo, InstanceExpression.Type, ec.CurrentType);
                                return false;
                        }
 
@@ -5477,7 +5495,7 @@ namespace Mono.CSharp {
 
                        bool must_do_cs1540_check = false;
                        if (getter != null &&
-                           !IsAccessorAccessible (ec.ContainerType, getter, out must_do_cs1540_check)) {
+                           !IsAccessorAccessible (ec.CurrentType, getter, out must_do_cs1540_check)) {
                                PropertyBase.PropertyMethod pm = TypeManager.GetMethod (getter) as PropertyBase.PropertyMethod;
                                if (pm != null && pm.HasCustomAccessModifier) {
                                        Report.SymbolRelatedToPreviousError (pm);
@@ -5564,7 +5582,7 @@ namespace Mono.CSharp {
                        }
 
                        bool must_do_cs1540_check;
-                       if (!IsAccessorAccessible (ec.ContainerType, setter, out must_do_cs1540_check)) {
+                       if (!IsAccessorAccessible (ec.CurrentType, setter, out must_do_cs1540_check)) {
                                PropertyBase.PropertyMethod pm = TypeManager.GetMethod (setter) as PropertyBase.PropertyMethod;
                                if (pm != null && pm.HasCustomAccessModifier) {
                                        Report.SymbolRelatedToPreviousError (pm);
@@ -5737,15 +5755,15 @@ namespace Mono.CSharp {
                        // If the event is local to this class, we transform ourselves into a FieldExpr
                        //
 
-                       if (EventInfo.DeclaringType == ec.ContainerType ||
-                           TypeManager.IsNestedChildOf(ec.ContainerType, EventInfo.DeclaringType)) {
+                       if (EventInfo.DeclaringType == ec.CurrentType ||
+                           TypeManager.IsNestedChildOf(ec.CurrentType, EventInfo.DeclaringType)) {
                                EventField mi = TypeManager.GetEventField (EventInfo);
 
                                if (mi != null) {
                                        if (!ec.IsInObsoleteScope)
                                                mi.CheckObsoleteness (loc);
 
-                                       if ((mi.ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0 && !ec.IsInCompoundAssignment)
+                                       if ((mi.ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0 && !ec.HasSet (EmitContext.Options.CompoundAssignmentScope))
                                                Error_AssignmentEventOnly ();
                                        
                                        FieldExpr ml = new FieldExpr (mi.BackingField.FieldBuilder, loc);
@@ -5755,8 +5773,8 @@ namespace Mono.CSharp {
                                        return ml.ResolveMemberAccess (ec, left, loc, original);
                                }
                        }
-                       
-                       if (left is This && !ec.IsInCompoundAssignment)                 
+
+                       if (left is This && !ec.HasSet (EmitContext.Options.CompoundAssignmentScope))                   
                                Error_AssignmentEventOnly ();
 
                        return base.ResolveMemberAccess (ec, left, loc, original);
@@ -5790,9 +5808,9 @@ namespace Mono.CSharp {
                        // TODO: Exact copy from PropertyExpr
                        //
                        if (must_do_cs1540_check && InstanceExpression != EmptyExpression.Null &&
-                           !TypeManager.IsInstantiationOfSameGenericType (InstanceExpression.Type, ec.ContainerType) &&
-                           !TypeManager.IsNestedChildOf (ec.ContainerType, InstanceExpression.Type) &&
-                           !TypeManager.IsSubclassOf (InstanceExpression.Type, ec.ContainerType)) {
+                           !TypeManager.IsInstantiationOfSameGenericType (InstanceExpression.Type, ec.CurrentType) &&
+                           !TypeManager.IsNestedChildOf (ec.CurrentType, InstanceExpression.Type) &&
+                           !TypeManager.IsSubclassOf (InstanceExpression.Type, ec.CurrentType)) {
                                Report.SymbolRelatedToPreviousError (EventInfo);
                                ErrorIsInaccesible (loc, TypeManager.CSharpSignature (EventInfo));
                                return false;
@@ -5823,8 +5841,8 @@ namespace Mono.CSharp {
                public override Expression DoResolve (EmitContext ec)
                {
                        bool must_do_cs1540_check;
-                       if (!(IsAccessorAccessible (ec.ContainerType, add_accessor, out must_do_cs1540_check) &&
-                             IsAccessorAccessible (ec.ContainerType, remove_accessor, out must_do_cs1540_check))) {
+                       if (!(IsAccessorAccessible (ec.CurrentType, add_accessor, out must_do_cs1540_check) &&
+                             IsAccessorAccessible (ec.CurrentType, remove_accessor, out must_do_cs1540_check))) {
                                Report.SymbolRelatedToPreviousError (EventInfo);
                                ErrorIsInaccesible (loc, TypeManager.CSharpSignature (EventInfo));
                                return null;
@@ -5833,7 +5851,7 @@ namespace Mono.CSharp {
                        if (!InstanceResolve (ec, must_do_cs1540_check))
                                return null;
 
-                       if (!ec.IsInCompoundAssignment) {
+                       if (!ec.HasSet (EmitContext.Options.CompoundAssignmentScope)) {
                                Error_CannotAssign ();
                                return null;
                        }
index 76807161988dc6097d9ab2bc94ab7bad2b0237f9..bc36a672b3f50a107c47347cd0f4cd8a33909aab 100644 (file)
@@ -405,11 +405,10 @@ namespace Mono.CSharp {
                                        if (method == null)
                                                throw new InternalErrorException ("did not find the the Host method");
 
-                                       EmitContext ec = method.CreateEmitContext (method.Parent, null);
-                                       bool unreach;
+                                       EmitContext ec = method.CreateEmitContext (null);
 
                                        try {
-                                               ec.ResolveTopBlock (null, method.Block, method.ParameterInfo, method, out unreach);
+                                               method.Block.Resolve (null, ec, method.ParameterInfo, method);
                                        } catch (CompletionResult cr){
                                                prefix = cr.BaseText;
                                                return cr.Result;
index 6748eb42b5dfb2047f0cef9e29091801e8ec373b..30af4eb42fc2575a56d5e7ca62ad02626502c99e 100644 (file)
@@ -356,7 +356,7 @@ namespace Mono.CSharp {
                                Error_PointerInsideExpressionTree ();
                                return null;
                        case Operator.UnaryNegation:
-                               if (ec.CheckState && user_op == null && !IsFloat (type))
+                               if (ec.HasSet (EmitContext.Options.CheckedScope) && user_op == null && !IsFloat (type))
                                        method_name = "NegateChecked";
                                else
                                        method_name = "Negate";
@@ -499,7 +499,7 @@ namespace Mono.CSharp {
                                break;
                                
                        case Operator.UnaryNegation:
-                               if (ec.CheckState && !IsFloat (type)) {
+                               if (ec.HasSet (EmitContext.Options.CheckedScope) && !IsFloat (type)) {
                                        ig.Emit (OpCodes.Ldc_I4_0);
                                        if (type == TypeManager.int64_type)
                                                ig.Emit (OpCodes.Conv_U8);
@@ -649,7 +649,7 @@ namespace Mono.CSharp {
                                is_fixed = fe != null && fe.IsFixed;
                        }
 
-                       if (!is_fixed && !ec.InFixedInitializer) {
+                       if (!is_fixed && !ec.HasSet (EmitContext.Options.FixedInitializerScope)) {
                                Error (212, "You can only take the address of unfixed expression inside of a fixed statement initializer");
                        }
 
@@ -690,7 +690,7 @@ namespace Mono.CSharp {
                        }
 
                        string op_name = CSharp.Operator.GetMetadataName (op_type);
-                       MethodGroupExpr user_op = MemberLookup (ec.ContainerType, expr.Type, op_name, MemberTypes.Method, AllBindingFlags, expr.Location) as MethodGroupExpr;
+                       MethodGroupExpr user_op = MemberLookup (ec.CurrentType, expr.Type, op_name, MemberTypes.Method, AllBindingFlags, expr.Location) as MethodGroupExpr;
                        if (user_op == null)
                                return null;
 
@@ -984,7 +984,7 @@ namespace Mono.CSharp {
                        else
                                op_name = Operator.GetMetadataName (Operator.OpType.Decrement);
 
-                       mg = MemberLookup (ec.ContainerType, type, op_name, MemberTypes.Method, AllBindingFlags, loc) as MethodGroupExpr;
+                       mg = MemberLookup (ec.CurrentType, type, op_name, MemberTypes.Method, AllBindingFlags, loc) as MethodGroupExpr;
 
                        if (mg != null) {
                                Arguments args = new Arguments (1);
@@ -1072,22 +1072,22 @@ namespace Mono.CSharp {
                        Binary.EmitOperatorOpcode (ec, op, t);
 
                        if (t == TypeManager.sbyte_type){
-                               if (ec.CheckState)
+                               if (ec.HasSet (EmitContext.Options.CheckedScope))
                                        ig.Emit (OpCodes.Conv_Ovf_I1);
                                else
                                        ig.Emit (OpCodes.Conv_I1);
                        } else if (t == TypeManager.byte_type){
-                               if (ec.CheckState)
+                               if (ec.HasSet (EmitContext.Options.CheckedScope))
                                        ig.Emit (OpCodes.Conv_Ovf_U1);
                                else
                                        ig.Emit (OpCodes.Conv_U1);
                        } else if (t == TypeManager.short_type){
-                               if (ec.CheckState)
+                               if (ec.HasSet (EmitContext.Options.CheckedScope))
                                        ig.Emit (OpCodes.Conv_Ovf_I2);
                                else
                                        ig.Emit (OpCodes.Conv_I2);
                        } else if (t == TypeManager.ushort_type || t == TypeManager.char_type){
-                               if (ec.CheckState)
+                               if (ec.HasSet (EmitContext.Options.CheckedScope))
                                        ig.Emit (OpCodes.Conv_Ovf_U2);
                                else
                                        ig.Emit (OpCodes.Conv_U2);
@@ -1432,7 +1432,7 @@ namespace Mono.CSharp {
                        Type etype = expr.Type;
 
                        if (!TypeManager.IsReferenceType (type) && !TypeManager.IsNullableType (type)) {
-                               if (probe_type_expr is TypeParameterExpr) {
+                               if (TypeManager.IsGenericParameter (type)) {
                                        Report.Error (413, loc,
                                                "The `as' operator cannot be used with a non-reference type parameter `{0}'. Consider adding `class' or a reference type constraint",
                                                probe_type_expr.GetSignatureForError ());
@@ -1789,7 +1789,7 @@ namespace Mono.CSharp {
                                //
                                // Start a new concat expression using converted expression
                                //
-                               return new StringConcat (ec, b.loc, b.left, b.right).Resolve (ec);
+                               return new StringConcat (b.loc, b.left, b.right).Resolve (ec);
                        }
                }
 
@@ -2145,7 +2145,7 @@ namespace Mono.CSharp {
 
                        switch (oper){
                        case Operator.Multiply:
-                               if (ec.CheckState){
+                               if (ec.HasSet (EmitContext.Options.CheckedScope)){
                                        if (l == TypeManager.int32_type || l == TypeManager.int64_type)
                                                opcode = OpCodes.Mul_Ovf;
                                        else if (!IsFloat (l))
@@ -2172,7 +2172,7 @@ namespace Mono.CSharp {
                                break;
 
                        case Operator.Addition:
-                               if (ec.CheckState){
+                               if (ec.HasSet (EmitContext.Options.CheckedScope)){
                                        if (l == TypeManager.int32_type || l == TypeManager.int64_type)
                                                opcode = OpCodes.Add_Ovf;
                                        else if (!IsFloat (l))
@@ -2184,7 +2184,7 @@ namespace Mono.CSharp {
                                break;
 
                        case Operator.Subtraction:
-                               if (ec.CheckState){
+                               if (ec.HasSet (EmitContext.Options.CheckedScope)){
                                        if (l == TypeManager.int32_type || l == TypeManager.int64_type)
                                                opcode = OpCodes.Sub_Ovf;
                                        else if (!IsFloat (l))
@@ -2625,7 +2625,7 @@ namespace Mono.CSharp {
                        Constant rc = right as Constant;
 
                        // The conversion rules are ignored in enum context but why
-                       if (!ec.InEnumContext && lc != null && rc != null && (TypeManager.IsEnumType (left.Type) || TypeManager.IsEnumType (right.Type))) {
+                       if (!ec.HasSet (EmitContext.Options.EnumScope) && lc != null && rc != null && (TypeManager.IsEnumType (left.Type) || TypeManager.IsEnumType (right.Type))) {
                                lc = EnumLiftUp (ec, lc, rc, loc);
                                if (lc != null)
                                        rc = EnumLiftUp (ec, rc, lc, loc);
@@ -3135,11 +3135,11 @@ namespace Mono.CSharp {
 
                        string op = GetOperatorMetadataName (user_oper);
 
-                       MethodGroupExpr left_operators = MemberLookup (ec.ContainerType, l, op, MemberTypes.Method, AllBindingFlags, loc) as MethodGroupExpr;
+                       MethodGroupExpr left_operators = MemberLookup (ec.CurrentType, l, op, MemberTypes.Method, AllBindingFlags, loc) as MethodGroupExpr;
                        MethodGroupExpr right_operators = null;
 
                        if (!TypeManager.IsEqual (r, l)) {
-                               right_operators = MemberLookup (ec.ContainerType, r, op, MemberTypes.Method, AllBindingFlags, loc) as MethodGroupExpr;
+                               right_operators = MemberLookup (ec.CurrentType, r, op, MemberTypes.Method, AllBindingFlags, loc) as MethodGroupExpr;
                                if (right_operators == null && left_operators == null)
                                        return null;
                        } else if (left_operators == null) {
@@ -3546,7 +3546,7 @@ namespace Mono.CSharp {
                public override void EmitSideEffect (EmitContext ec)
                {
                        if ((oper & Operator.LogicalMask) != 0 ||
-                           (ec.CheckState && (oper == Operator.Multiply || oper == Operator.Addition || oper == Operator.Subtraction))) {
+                           (ec.HasSet (EmitContext.Options.CheckedScope) && (oper == Operator.Multiply || oper == Operator.Addition || oper == Operator.Subtraction))) {
                                base.EmitSideEffect (ec);
                        } else {
                                left.EmitSideEffect (ec);
@@ -3572,7 +3572,7 @@ namespace Mono.CSharp {
                        MemberAccess binder = DynamicExpressionStatement.GetBinderNamespace (loc);
 
                        binder_args.Add (new Argument (new MemberAccess (new MemberAccess (sle, "ExpressionType", loc), GetOperatorExpressionTypeName (), loc)));
-                       binder_args.Add (new Argument (new BoolLiteral (ec.CheckState, loc)));
+                       binder_args.Add (new Argument (new BoolLiteral (ec.HasSet (EmitContext.Options.CheckedScope), loc)));
 
                        bool member_access = left is DynamicMemberBinder || right is DynamicMemberBinder;
                        binder_args.Add (new Argument (new BoolLiteral (member_access, loc)));
@@ -3593,7 +3593,7 @@ namespace Mono.CSharp {
                        
                        switch (oper) {
                        case Operator.Addition:
-                               if (method == null && ec.CheckState && !IsFloat (type))
+                               if (method == null && ec.HasSet (EmitContext.Options.CheckedScope) && !IsFloat (type))
                                        method_name = "AddChecked";
                                else
                                        method_name = "Add";
@@ -3647,7 +3647,7 @@ namespace Mono.CSharp {
                                method_name = "Modulo";
                                break;
                        case Operator.Multiply:
-                               if (method == null && ec.CheckState && !IsFloat (type))
+                               if (method == null && ec.HasSet (EmitContext.Options.CheckedScope) && !IsFloat (type))
                                        method_name = "MultiplyChecked";
                                else
                                        method_name = "Multiply";
@@ -3656,7 +3656,7 @@ namespace Mono.CSharp {
                                method_name = "RightShift";
                                break;
                        case Operator.Subtraction:
-                               if (method == null && ec.CheckState && !IsFloat (type))
+                               if (method == null && ec.HasSet (EmitContext.Options.CheckedScope) && !IsFloat (type))
                                        method_name = "SubtractChecked";
                                else
                                        method_name = "Subtract";
@@ -3687,15 +3687,15 @@ namespace Mono.CSharp {
        public class StringConcat : Expression {
                Arguments arguments;
                
-               public StringConcat (EmitContext ec, Location loc, Expression left, Expression right)
+               public StringConcat (Location loc, Expression left, Expression right)
                {
                        this.loc = loc;
                        type = TypeManager.string_type;
                        eclass = ExprClass.Value;
 
                        arguments = new Arguments (2);
-                       Append (ec, left);
-                       Append (ec, right);
+                       Append (left);
+                       Append (right);
                }
 
                public override Expression CreateExpressionTree (EmitContext ec)
@@ -3741,7 +3741,7 @@ namespace Mono.CSharp {
                        return this;
                }
                
-               public void Append (EmitContext ec, Expression operand)
+               public void Append (Expression operand)
                {
                        //
                        // Constant folding
@@ -4817,7 +4817,7 @@ namespace Mono.CSharp {
                                        return null;
                                }
                                
-                               mg = ec.TypeContainer.LookupExtensionMethod (me.Type, me.Name, loc);
+                               mg = ec.LookupExtensionMethod (me.Type, me.Name, loc);
                                if (mg == null) {
                                        Report.Error (1955, loc, "The member `{0}' cannot be used as method or delegate",
                                                expr_resolved.GetSignatureForError ());
@@ -5437,7 +5437,7 @@ namespace Mono.CSharp {
 
                        method = ml as MethodGroupExpr;
                        if (method == null) {
-                               ml.Error_UnexpectedKind (ec.DeclContainer, "method group", loc);
+                               ml.Error_UnexpectedKind (ResolveFlags.MethodGroup, loc);
                                return null;
                        }
 
@@ -6493,7 +6493,7 @@ namespace Mono.CSharp {
                {
                        eclass = ExprClass.Variable;
                        if (type == null)
-                               type = ec.ContainerType;
+                               type = ec.CurrentType;
                        return this;
                }
 
@@ -6583,13 +6583,13 @@ namespace Mono.CSharp {
 
                public static bool IsThisAvailable (EmitContext ec)
                {
-                       if (ec.IsStatic || ec.IsInFieldInitializer)
+                       if (ec.IsStatic || ec.HasAny (EmitContext.Options.FieldInitializerScope | EmitContext.Options.BaseInitializer | EmitContext.Options.ConstantScope))
                                return false;
 
                        if (ec.CurrentAnonymousMethod == null)
                                return true;
 
-                       if (ec.TypeContainer is Struct && ec.CurrentIterator == null)
+                       if (ec.CurrentType.IsValueType && ec.CurrentIterator == null)
                                return false;
 
                        return true;
@@ -6601,23 +6601,21 @@ namespace Mono.CSharp {
                                return true;
 
                        eclass = ExprClass.Variable;
-
-                       if (ec.TypeContainer.CurrentType != null)
-                               type = ec.TypeContainer.CurrentType;
-                       else
-                               type = ec.ContainerType;
+                       type = ec.CurrentType;
 
                        if (!IsThisAvailable (ec)) {
-                               if (ec.IsStatic) {
+                               if (ec.IsStatic && !ec.HasSet (EmitContext.Options.ConstantScope)) {
                                        Error (26, "Keyword `this' is not valid in a static property, static method, or static field initializer");
-                               } else {
+                               } else if (ec.CurrentAnonymousMethod != null) {
                                        Report.Error (1673, loc,
                                                "Anonymous methods inside structs cannot access instance members of `this'. " +
                                                "Consider copying `this' to a local variable outside the anonymous method and using the local instead");
+                               } else {
+                                       Error (27, "Keyword `this' is not available in the current context");
                                }
                        }
 
-                       is_struct = ec.TypeContainer is Struct;
+                       is_struct = type.IsValueType;
 
                        if (block != null) {
                                if (block.Toplevel.ThisVariable != null)
@@ -6657,15 +6655,7 @@ namespace Mono.CSharp {
                
                public override Expression DoResolve (EmitContext ec)
                {
-                       if (!ResolveBase (ec))
-                               return null;
-
-
-                       if (ec.IsInFieldInitializer) {
-                               Error (27, "Keyword `this' is not available in the current context");
-                               return null;
-                       }
-                       
+                       ResolveBase (ec);
                        return this;
                }
 
@@ -6677,7 +6667,7 @@ namespace Mono.CSharp {
                        if (variable_info != null)
                                variable_info.SetAssigned (ec);
 
-                       if (ec.TypeContainer is Class){
+                       if (ec.CurrentType.IsClass){
                                if (right_side == EmptyExpression.UnaryAddress)
                                        Report.Error (459, loc, "Cannot take the address of `this' because it is read-only");
                                else if (right_side == EmptyExpression.OutAccess)
@@ -6740,11 +6730,9 @@ namespace Mono.CSharp {
                        eclass = ExprClass.Variable;
                        type = TypeManager.runtime_argument_handle_type;
 
-                       if (ec.IsInFieldInitializer || !ec.CurrentBlock.Toplevel.Parameters.HasArglist) 
-                       {
+                       if (ec.HasSet (EmitContext.Options.FieldInitializerScope) || !ec.CurrentBlock.Toplevel.Parameters.HasArglist) {
                                Error (190, "The __arglist construct is valid only within " +
                                       "a variable argument method");
-                               return this;
                        }
 
                        return this;
@@ -7227,7 +7215,7 @@ namespace Mono.CSharp {
                        }
 
                        int errors = Report.Errors;
-                       expr = ec.DeclContainer.NamespaceEntry.LookupAlias (alias);
+                       expr = ec.LookupNamespaceAlias (alias);
                        if (expr == null) {
                                if (errors == Report.Errors)
                                        Report.Error (432, loc, "Alias `{0}' not found", alias);
@@ -7326,10 +7314,10 @@ namespace Mono.CSharp {
 
                        Namespace ns = expr_resolved as Namespace;
                        if (ns != null) {
-                               FullNamedExpression retval = ns.Lookup (ec.DeclContainer, LookupIdentifier, loc);
+                               FullNamedExpression retval = ns.Lookup (LookupIdentifier, loc);
 
                                if (retval == null)
-                                       ns.Error_NamespaceDoesNotExist (ec.DeclContainer, loc, LookupIdentifier);
+                                       ns.Error_NamespaceDoesNotExist (loc, LookupIdentifier);
                                else if (targs != null)
                                        retval = new GenericTypeExpr (retval.Type, targs, loc).ResolveAsTypeStep (ec, false);
 
@@ -7365,11 +7353,11 @@ namespace Mono.CSharp {
 
                        Expression member_lookup;
                        member_lookup = MemberLookup (
-                               ec.ContainerType, expr_type, expr_type, Name, loc);
+                               ec.CurrentType, expr_type, expr_type, Name, loc);
 
                        if (member_lookup == null && targs != null) {
                                member_lookup = MemberLookup (
-                                       ec.ContainerType, expr_type, expr_type, LookupIdentifier, loc);
+                                       ec.CurrentType, expr_type, expr_type, LookupIdentifier, loc);
                        }
 
                        if (member_lookup == null) {
@@ -7381,7 +7369,7 @@ namespace Mono.CSharp {
                                if (expr_eclass == ExprClass.Value || expr_eclass == ExprClass.Variable ||
                                        expr_eclass == ExprClass.IndexerAccess || expr_eclass == ExprClass.PropertyAccess ||
                                        expr_eclass == ExprClass.EventAccess) {
-                                       ExtensionMethodGroupExpr ex_method_lookup = ec.TypeContainer.LookupExtensionMethod (expr_type, Name, loc);
+                                       ExtensionMethodGroupExpr ex_method_lookup = ec.LookupExtensionMethod (expr_type, Name, loc);
                                        if (ex_method_lookup != null) {
                                                ex_method_lookup.ExtensionExpression = expr_resolved;
 
@@ -7395,7 +7383,7 @@ namespace Mono.CSharp {
 
                                expr = expr_resolved;
                                member_lookup = Error_MemberLookupFailed (
-                                       ec.ContainerType, expr_type, expr_type, Name, null,
+                                       ec.CurrentType, expr_type, expr_type, Name, null,
                                        AllMemberTypes, AllBindingFlags);
                                if (member_lookup == null)
                                        return null;
@@ -7410,7 +7398,7 @@ namespace Mono.CSharp {
                                        return null;
                                }
 
-                               if (!texpr.CheckAccessLevel (ec.DeclContainer)) {
+                               if (!texpr.CheckAccessLevel (ec.GenericDeclContainer)) {
                                        Report.SymbolRelatedToPreviousError (member_lookup.Type);
                                        ErrorIsInaccesible (loc, TypeManager.CSharpName (member_lookup.Type));
                                        return null;
@@ -7486,10 +7474,10 @@ namespace Mono.CSharp {
 
                        Namespace ns = expr_resolved as Namespace;
                        if (ns != null) {
-                               FullNamedExpression retval = ns.Lookup (rc.DeclContainer, LookupIdentifier, loc);
+                               FullNamedExpression retval = ns.Lookup (LookupIdentifier, loc);
 
                                if (retval == null && !silent)
-                                       ns.Error_NamespaceDoesNotExist (rc.DeclContainer, loc, LookupIdentifier);
+                                       ns.Error_NamespaceDoesNotExist (loc, LookupIdentifier);
                                else if (targs != null)
                                        retval = new GenericTypeExpr (retval.Type, targs, loc).ResolveAsTypeStep (rc, silent);
 
@@ -7500,15 +7488,15 @@ namespace Mono.CSharp {
                        if (tnew_expr == null)
                                return null;
 
-                       if (tnew_expr is TypeParameterExpr) {
+                       Type expr_type = tnew_expr.Type;
+                       if (TypeManager.IsGenericParameter (expr_type)) {
                                Report.Error (704, loc, "A nested type cannot be specified through a type parameter `{0}'",
                                        tnew_expr.GetSignatureForError ());
                                return null;
                        }
 
-                       Type expr_type = tnew_expr.Type;
                        Expression member_lookup = MemberLookup (
-                               rc.DeclContainer.TypeBuilder, expr_type, expr_type, LookupIdentifier,
+                               rc.CurrentType, expr_type, expr_type, LookupIdentifier,
                                MemberTypes.NestedType, BindingFlags.Public | BindingFlags.NonPublic, loc);
                        if (member_lookup == null) {
                                if (silent)
@@ -7550,7 +7538,7 @@ namespace Mono.CSharp {
                protected virtual void Error_IdentifierNotFound (IResolveContext rc, FullNamedExpression expr_type, string identifier)
                {
                        Expression member_lookup = MemberLookup (
-                               rc.DeclContainer.TypeBuilder, expr_type.Type, expr_type.Type, SimpleName.RemoveGenericArity (identifier),
+                               rc.CurrentType, expr_type.Type, expr_type.Type, SimpleName.RemoveGenericArity (identifier),
                                MemberTypes.NestedType, BindingFlags.Public | BindingFlags.NonPublic, loc);
 
                        if (member_lookup != null) {
@@ -7563,7 +7551,7 @@ namespace Mono.CSharp {
                        }
 
                        member_lookup = MemberLookup (
-                               rc.DeclContainer.TypeBuilder, expr_type.Type, expr_type.Type, identifier,
+                               rc.CurrentType, expr_type.Type, expr_type.Type, identifier,
                                        MemberTypes.All, BindingFlags.Public | BindingFlags.NonPublic, loc);
 
                        if (member_lookup == null) {
@@ -7623,13 +7611,13 @@ namespace Mono.CSharp {
                
                public override Expression CreateExpressionTree (EmitContext ec)
                {
-                       using (ec.With (EmitContext.Flags.AllCheckStateFlags, true))
+                       using (ec.With (EmitContext.Options.AllCheckStateFlags, true))
                                return Expr.CreateExpressionTree (ec);
                }
 
                public override Expression DoResolve (EmitContext ec)
                {
-                       using (ec.With (EmitContext.Flags.AllCheckStateFlags, true))
+                       using (ec.With (EmitContext.Options.AllCheckStateFlags, true))
                                Expr = Expr.Resolve (ec);
                        
                        if (Expr == null)
@@ -7645,13 +7633,13 @@ namespace Mono.CSharp {
 
                public override void Emit (EmitContext ec)
                {
-                       using (ec.With (EmitContext.Flags.AllCheckStateFlags, true))
+                       using (ec.With (EmitContext.Options.AllCheckStateFlags, true))
                                Expr.Emit (ec);
                }
 
                public override void EmitBranchable (EmitContext ec, Label target, bool on_true)
                {
-                       using (ec.With (EmitContext.Flags.AllCheckStateFlags, true))
+                       using (ec.With (EmitContext.Options.AllCheckStateFlags, true))
                                Expr.EmitBranchable (ec, target, on_true);
                }
 
@@ -7683,13 +7671,13 @@ namespace Mono.CSharp {
                
                public override Expression CreateExpressionTree (EmitContext ec)
                {
-                       using (ec.With (EmitContext.Flags.AllCheckStateFlags, false))
+                       using (ec.With (EmitContext.Options.AllCheckStateFlags, false))
                                return Expr.CreateExpressionTree (ec);
                }
 
                public override Expression DoResolve (EmitContext ec)
                {
-                       using (ec.With (EmitContext.Flags.AllCheckStateFlags, false))
+                       using (ec.With (EmitContext.Options.AllCheckStateFlags, false))
                                Expr = Expr.Resolve (ec);
 
                        if (Expr == null)
@@ -7705,13 +7693,13 @@ namespace Mono.CSharp {
 
                public override void Emit (EmitContext ec)
                {
-                       using (ec.With (EmitContext.Flags.AllCheckStateFlags, false))
+                       using (ec.With (EmitContext.Options.AllCheckStateFlags, false))
                                Expr.Emit (ec);
                }
                
                public override void EmitBranchable (EmitContext ec, Label target, bool on_true)
                {
-                       using (ec.With (EmitContext.Flags.AllCheckStateFlags, false))
+                       using (ec.With (EmitContext.Options.AllCheckStateFlags, false))
                                Expr.EmitBranchable (ec, target, on_true);
                }
 
@@ -8374,7 +8362,7 @@ namespace Mono.CSharp {
                protected virtual void CommonResolve (EmitContext ec)
                {
                        indexer_type = instance_expr.Type;
-                       current_type = ec.ContainerType;
+                       current_type = ec.CurrentType;
                }
 
                public override Expression DoResolve (EmitContext ec)
@@ -8385,8 +8373,8 @@ namespace Mono.CSharp {
                public override Expression DoResolveLValue (EmitContext ec, Expression right_side)
                {
                        if (right_side == EmptyExpression.OutAccess) {
-                               Report.Error (206, loc, "A property or indexer `{0}' may not be passed as an out or ref parameter",
-                                             GetSignatureForError ());
+                               Report.Error (206, loc,
+                                       "A property or indexer may not be passed as an out or ref parameter");
                                return null;
                        }
 
@@ -8474,7 +8462,7 @@ namespace Mono.CSharp {
                        }
 
                        bool must_do_cs1540_check;
-                       if (!IsAccessorAccessible (ec.ContainerType, accessor, out must_do_cs1540_check)) {
+                       if (!IsAccessorAccessible (ec.CurrentType, accessor, out must_do_cs1540_check)) {
                                if (set == null)
                                        set = pi.GetSetMethod (true);
                                else
@@ -8648,7 +8636,7 @@ namespace Mono.CSharp {
                Expression CommonResolve (EmitContext ec)
                {
                        Expression member_lookup;
-                       Type current_type = ec.ContainerType;
+                       Type current_type = ec.CurrentType;
                        Type base_type = current_type.BaseType;
 
                        if (!This.IsThisAvailable (ec)) {
@@ -8660,10 +8648,10 @@ namespace Mono.CSharp {
                                return null;
                        }
                        
-                       member_lookup = MemberLookup (ec.ContainerType, null, base_type, Identifier,
+                       member_lookup = MemberLookup (ec.CurrentType, null, base_type, Identifier,
                                                      AllMemberTypes, AllBindingFlags, loc);
                        if (member_lookup == null) {
-                               Error_MemberLookupFailed (ec.ContainerType, base_type, base_type, Identifier,
+                               Error_MemberLookupFailed (ec.CurrentType, base_type, base_type, Identifier,
                                        null, AllMemberTypes, AllBindingFlags);
                                return null;
                        }
@@ -8717,7 +8705,7 @@ namespace Mono.CSharp {
                {
                        instance_expr = ec.GetThis (loc);
 
-                       current_type = ec.ContainerType.BaseType;
+                       current_type = ec.CurrentType.BaseType;
                        indexer_type = current_type;
                }
 
@@ -9104,7 +9092,7 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-                       if (ec.InCatch || ec.InFinally) {
+                       if (ec.HasAny (EmitContext.Options.CatchScope | EmitContext.Options.FinallyScope)) {
                                Error (255, "Cannot use stackalloc in finally or catch");
                                return null;
                        }
@@ -9667,7 +9655,7 @@ namespace Mono.CSharp {
                {
                        AnonymousTypeClass anonymous_type;
 
-                       if (!ec.IsAnonymousMethodAllowed) {
+                       if (ec.HasSet (EmitContext.Options.ConstantScope)) {
                                Report.Error (836, loc, "Anonymous types cannot be used in this expression");
                                return null;
                        }
index 35be74a66624ca0afaa8a673544da5f1f2235aad..367d3fdff1b7be2f8052c53f2e2a5e48597c431a 100644 (file)
@@ -128,6 +128,11 @@ namespace Mono.CSharp
                public void ErrorInvalidVariance (MemberCore mc, Variance v)
                {
                }
+               
+               public static TypeParameter FindTypeParameter (TypeParameter[] all, string name)
+               {
+                       throw new NotImplementedException ();
+               }
 
                //
                // MemberContainer
@@ -429,6 +434,13 @@ namespace Mono.CSharp
 
        public class TypeInferenceContext
        {
+               public Type[] InferredTypeArguments;
+               
+               public void AddCommonTypeBound (Type type)
+               {
+                       throw new NotImplementedException ();
+               }
+               
                public void ExactInference (Type u, Type v)
                {
                        throw new NotImplementedException ();
@@ -438,6 +450,11 @@ namespace Mono.CSharp
                {
                        throw new NotImplementedException ();           
                }
+               
+               public bool FixAllTypes ()
+               {
+                       return false;
+               }
        }
        
        partial class TypeManager
index 99f23607f401412dbc7f5b288e66c8f60187cf56..1f122649968f490fc8922b5df2f28aca0966951d 100644 (file)
@@ -321,8 +321,7 @@ namespace Mono.CSharp {
                                        return false;
                                }
 
-                               TypeParameterExpr texpr = expr as TypeParameterExpr;
-                               if (texpr != null)
+                               if (TypeManager.IsGenericParameter (expr.Type))
                                        type_param_constraints.Add (expr);
                                else if (expr.IsInterface)
                                        iface_constraints.Add (expr);
@@ -367,7 +366,7 @@ namespace Mono.CSharp {
                                list.Add (iface_constraint.Type);
                        }
 
-                       foreach (TypeParameterExpr expr in type_param_constraints) {
+                       foreach (TypeExpr expr in type_param_constraints) {
                                foreach (Type type in list) {
                                        if (!type.Equals (expr.Type))
                                                continue;
@@ -414,6 +413,11 @@ namespace Mono.CSharp {
                                                      TypeManager.CSharpName (class_constraint_type));
                                        return false;
                                }
+
+                               if (TypeManager.IsDynamicType (class_constraint_type)) {
+                                       Report.Error (1967, loc, "A constraint cannot be the dynamic type");
+                                       return false;
+                               }
                        }
 
                        if (class_constraint_type != null)
@@ -430,11 +434,11 @@ namespace Mono.CSharp {
                        return true;
                }
 
-               bool CheckTypeParameterConstraints (TypeParameter tparam, ref TypeExpr prevConstraint, ArrayList seen)
+               bool CheckTypeParameterConstraints (Type tparam, ref TypeExpr prevConstraint, ArrayList seen)
                {
                        seen.Add (tparam);
 
-                       Constraints constraints = tparam.Constraints;
+                       Constraints constraints = TypeManager.LookupTypeParameter (tparam).Constraints;
                        if (constraints == null)
                                return true;
 
@@ -472,15 +476,15 @@ namespace Mono.CSharp {
                        if (constraints.type_param_constraints == null)
                                return true;
 
-                       foreach (TypeParameterExpr expr in constraints.type_param_constraints) {
-                               if (seen.Contains (expr.TypeParameter)) {
+                       foreach (TypeExpr expr in constraints.type_param_constraints) {
+                               if (seen.Contains (expr.Type)) {
                                        Report.Error (454, loc, "Circular constraint " +
                                                      "dependency involving `{0}' and `{1}'",
                                                      tparam.Name, expr.GetSignatureForError ());
                                        return false;
                                }
 
-                               if (!CheckTypeParameterConstraints (expr.TypeParameter, ref prevConstraint, seen))
+                               if (!CheckTypeParameterConstraints (expr.Type, ref prevConstraint, seen))
                                        return false;
                        }
 
@@ -509,8 +513,8 @@ namespace Mono.CSharp {
                        if (type_param_constraints.Count != 0) {
                                ArrayList seen = new ArrayList ();
                                TypeExpr prev_constraint = class_constraint;
-                               foreach (TypeParameterExpr expr in type_param_constraints) {
-                                       if (!CheckTypeParameterConstraints (expr.TypeParameter, ref prev_constraint, seen))
+                               foreach (TypeExpr expr in type_param_constraints) {
+                                       if (!CheckTypeParameterConstraints (expr.Type, ref prev_constraint, seen))
                                                return false;
                                        seen.Clear ();
                                }
@@ -857,6 +861,16 @@ namespace Mono.CSharp {
                        return true;
                }
 
+               public static TypeParameter FindTypeParameter (TypeParameter[] tparams, string name)
+               {
+                       foreach (var tp in tparams) {
+                               if (tp.Name == name)
+                                       return tp;
+                       }
+
+                       return null;
+               }
+
                public void SetConstraints (GenericTypeParameterBuilder type)
                {
                        GenericParameterAttributes attr = GenericParameterAttributes.None;
@@ -1130,17 +1144,11 @@ namespace Mono.CSharp {
        ///   A TypeExpr which already resolved to a type parameter.
        /// </summary>
        public class TypeParameterExpr : TypeExpr {
-               TypeParameter type_parameter;
-
-               public TypeParameter TypeParameter {
-                       get {
-                               return type_parameter;
-                       }
-               }
                
                public TypeParameterExpr (TypeParameter type_parameter, Location loc)
                {
-                       this.type_parameter = type_parameter;
+                       this.type = type_parameter.Type;
+                       this.eclass = ExprClass.TypeParameter;
                        this.loc = loc;
                }
 
@@ -1151,8 +1159,6 @@ namespace Mono.CSharp {
 
                public override FullNamedExpression ResolveAsTypeStep (IResolveContext ec, bool silent)
                {
-                       type = type_parameter.Type;
-                       eclass = ExprClass.TypeParameter;
                        return this;
                }
 
@@ -1744,6 +1750,12 @@ namespace Mono.CSharp {
                        this.parameters = parameters;
                }
 
+               public override TypeParameter[] CurrentTypeParameters {
+                       get {
+                               return base.type_params;
+                       }
+               }
+
                public override TypeBuilder DefineType ()
                {
                        throw new Exception ();
@@ -2373,12 +2385,29 @@ namespace Mono.CSharp {
                        }
                }
 
+               // 
+               // Used together with AddCommonTypeBound fo implement
+               // 7.4.2.13 Finding the best common type of a set of expressions
+               //
+               public TypeInferenceContext ()
+               {
+                       fixed_types = new Type [1];
+                       unfixed_types = new Type [1];
+                       unfixed_types[0] = InternalType.Arglist; // it can be any internal type
+                       bounds = new ArrayList [1];
+               }
+
                public Type[] InferredTypeArguments {
                        get {
                                return fixed_types;
                        }
                }
 
+               public void AddCommonTypeBound (Type type)
+               {
+                       AddToBounds (new BoundInfo (type, BoundKind.Lower), 0);
+               }
+
                void AddToBounds (BoundInfo bound, int index)
                {
                        //
@@ -2566,7 +2595,11 @@ namespace Mono.CSharp {
 
                        if (candidates.Count == 1) {
                                unfixed_types[i] = null;
-                               fixed_types[i] = ((BoundInfo) candidates[0]).Type;
+                               Type t = ((BoundInfo) candidates[0]).Type;
+                               if (t == TypeManager.null_type)
+                                       return false;
+
+                               fixed_types [i] = t;
                                return true;
                        }
 
index ddd316fa14cef277eb578f740bc398dbde7fef4f..354dab8db92bf2c48433c3e2573b69566ce249bc 100644 (file)
@@ -35,14 +35,6 @@ namespace Mono.CSharp {
 
                public static bool CheckContext (EmitContext ec, Location loc)
                {
-                       for (Block block = ec.CurrentBlock; block != null; block = block.Parent) {
-                               if (!block.Unsafe)
-                                       continue;
-
-                               Report.Error (1629, loc, "Unsafe code may not appear in iterators");
-                               return false;
-                       }
-
                        //
                        // We can't use `ec.InUnsafe' here because it's allowed to have an iterator
                        // inside an unsafe class.  See test-martin-29.cs for an example.
@@ -190,10 +182,10 @@ namespace Mono.CSharp {
                                Block = new ToplevelBlock (host.Iterator.Container.Toplevel, ParametersCompiled.EmptyReadOnlyParameters, Location);
                        }
 
-                       public override EmitContext CreateEmitContext (DeclSpace tc, ILGenerator ig)
+                       public override EmitContext CreateEmitContext (ILGenerator ig)
                        {
                                EmitContext ec = new EmitContext (
-                                       this, tc, this.ds, Location, ig, MemberType, ModFlags, false);
+                                       this, this.ds, ig, MemberType);
 
                                ec.CurrentAnonymousMethod = host.Iterator;
                                return ec;
index 81108fa7533b7cbbd5e2915f2399a52816e2231e..244b8d942e22b6cecad6dc952cb7b77f03c6bb07 100644 (file)
@@ -169,6 +169,8 @@ namespace Mono.CSharp {
        //
        public class ContextualReturn : Return
        {
+               ExpressionStatement statement;
+
                public ContextualReturn (Expression expr)
                        : base (expr, expr.Location)
                {
@@ -181,8 +183,8 @@ namespace Mono.CSharp {
 
                public override void Emit (EmitContext ec)
                {
-                       if (ec.ReturnType == TypeManager.void_type) {
-                               ((ExpressionStatement) Expr).EmitStatement (ec);
+                       if (statement != null) {
+                               statement.EmitStatement (ec);
                                ec.ig.Emit (OpCodes.Ret);
                                return;
                        }
@@ -191,7 +193,7 @@ namespace Mono.CSharp {
                }
 
                protected override bool DoResolve (EmitContext ec)
-               {       
+               {
                        //
                        // When delegate returns void, only expression statements can be used
                        //
@@ -199,12 +201,12 @@ namespace Mono.CSharp {
                                Expr = Expr.Resolve (ec);
                                if (Expr == null)
                                        return false;
-                               
-                               if (Expr is ExpressionStatement)
-                                       return true;
-                               
-                               Expr.Error_InvalidExpressionStatement ();
-                               return false;
+
+                               statement = Expr as ExpressionStatement;
+                               if (statement == null)
+                                       Expr.Error_InvalidExpressionStatement ();
+
+                               return true;
                        }
 
                        return base.DoResolve (ec);
index bc2c6dc7b4fa31de99e598e8a3e5826df17b5fec..135efd556dedcd0ec2a59c2574dfd430ee3a21e8 100644 (file)
@@ -271,12 +271,12 @@ namespace Mono.CSharp.Linq
                {
                }
 
-               protected static Expression CreateRangeVariableType (ToplevelBlock block, TypeContainer container, LocatedToken name, Expression init)
+               protected static Expression CreateRangeVariableType (ToplevelBlock block, IResolveContext context, LocatedToken name, Expression init)
                {
                        ArrayList args = new ArrayList (2);
                        args.Add (new AnonymousTypeParameter (block.Parameters [0]));
                        args.Add (new RangeAnonymousTypeParameter (init, name));
-                       return new AnonymousTypeDeclaration (args, container, name.Location);
+                       return new AnonymousTypeDeclaration (args, context.CurrentTypeDefinition, name.Location);
                }
        }
 
@@ -409,7 +409,7 @@ namespace Mono.CSharp.Linq
                                result_selector_expr = next.expr;
                                next = next.next;
                        } else {
-                               result_selector_expr = CreateRangeVariableType (block, (TypeContainer) ec.TypeContainer, into_variable,
+                               result_selector_expr = CreateRangeVariableType (block, ec.ResolveContext, into_variable,
                                        new SimpleName (into_variable.Value, into_variable.Location));
                        }
 
@@ -519,7 +519,7 @@ namespace Mono.CSharp.Linq
                                result_selector_expr = next.expr;
                                next = next.next;
                        } else {
-                               result_selector_expr = CreateRangeVariableType (block, (TypeContainer)ec.TypeContainer, lt, new SimpleName (lt.Value, lt.Location));
+                               result_selector_expr = CreateRangeVariableType (block, ec.ResolveContext, lt, new SimpleName (lt.Value, lt.Location));
                        }
 
                        LambdaExpression result_selector = new LambdaExpression (lt.Location);
index 2cfbea142b6490861577c7834a849f9f0ac310ba..d1bbf22cd3826dd7afeaee03d4ee07b152bb6e1e 100644 (file)
@@ -295,7 +295,7 @@ namespace Mono.CSharp {
                        retval.AddAssemblyReference (assembly);
                }
 
-               public override void Error_NamespaceDoesNotExist(DeclSpace ds, Location loc, string name)
+               public override void Error_NamespaceDoesNotExist(Location loc, string name)
                {
                        Report.Error (400, loc, "The type or namespace name `{0}' could not be found in the global namespace (are you missing an assembly reference?)",
                                name);
@@ -406,10 +406,10 @@ namespace Mono.CSharp {
                        return this;
                }
 
-               public virtual void Error_NamespaceDoesNotExist (DeclSpace ds, Location loc, string name)
+               public virtual void Error_NamespaceDoesNotExist (Location loc, string name)
                {
                        if (name.IndexOf ('`') > 0) {
-                               FullNamedExpression retval = Lookup (ds, SimpleName.RemoveGenericArity (name), loc);
+                               FullNamedExpression retval = Lookup (SimpleName.RemoveGenericArity (name), loc);
                                if (retval != null) {
                                        Error_TypeArgumentsCannotBeUsed (retval, loc);
                                        return;
@@ -553,7 +553,7 @@ namespace Mono.CSharp {
                        return null;
                }
 
-               public FullNamedExpression Lookup (DeclSpace ds, string name, Location loc)
+               public FullNamedExpression Lookup (string name, Location loc)
                {
                        if (namespaces.Contains (name))
                                return (Namespace) namespaces [name];
@@ -564,7 +564,7 @@ namespace Mono.CSharp {
                //
                // Completes types with the given `prefix' and stores the results in `result'
                //
-               public void CompletionGetTypesStartingWith (DeclSpace ds, string prefix, Hashtable result)
+               public void CompletionGetTypesStartingWith (string prefix, Hashtable result)
                {
                        int l = fullname.Length + 1;
                        ICollection res = root.CompletionGetTypesStartingWith (fullname + "." + prefix);
@@ -789,13 +789,8 @@ namespace Mono.CSharp {
                                        return null;
                                }
 
-                               TypeExpr te = resolved as TypeExpr;
-                               if (te != null) {
-                                       if (!te.CheckAccessLevel (rc.DeclContainer)) {
-                                               Report.SymbolRelatedToPreviousError (te.Type);
-                                               Expression.ErrorIsInaccesible (resolved.Location, resolved.GetSignatureForError ());
-                                       }
-                               }
+                               if (resolved is TypeExpr)
+                                       resolved = resolved.ResolveAsBaseTerminal (rc, false);
 
                                return resolved;
                        }
@@ -1040,15 +1035,9 @@ namespace Mono.CSharp {
                /// Does extension methods look up to find a method which matches name and extensionType.
                /// Search starts from this namespace and continues hierarchically up to top level.
                ///
-               public ExtensionMethodGroupExpr LookupExtensionMethod (Type extensionType, ClassOrStruct currentClass, string name, Location loc)
+               public ExtensionMethodGroupExpr LookupExtensionMethod (Type extensionType, string name, Location loc)
                {
                        ArrayList candidates = null;
-                       if (currentClass != null) {
-                               candidates = ns.LookupExtensionMethod (extensionType, currentClass, name);
-                               if (candidates != null)
-                                       return new ExtensionMethodGroupExpr (candidates, this, extensionType, loc);
-                       }
-
                        foreach (Namespace n in GetUsingTable ()) {
                                ArrayList a = n.LookupExtensionMethod (extensionType, null, name);
                                if (a == null)
@@ -1081,21 +1070,21 @@ namespace Mono.CSharp {
                        //
                        // Continue in parent scope
                        //
-                       return parent.LookupExtensionMethod (extensionType, currentClass, name, loc);
+                       return parent.LookupExtensionMethod (extensionType, name, loc);
                }
 
-               public FullNamedExpression LookupNamespaceOrType (DeclSpace ds, string name, Location loc, bool ignore_cs0104)
+               public FullNamedExpression LookupNamespaceOrType (string name, Location loc, bool ignore_cs0104)
                {
                        // Precondition: Only simple names (no dots) will be looked up with this function.
                        FullNamedExpression resolved = null;
                        for (NamespaceEntry curr_ns = this; curr_ns != null; curr_ns = curr_ns.ImplicitParent) {
-                               if ((resolved = curr_ns.Lookup (ds, name, loc, ignore_cs0104)) != null)
+                               if ((resolved = curr_ns.Lookup (name, loc, ignore_cs0104)) != null)
                                        break;
                        }
                        return resolved;
                }
 
-               public ICollection CompletionGetTypesStartingWith (DeclSpace ds, string prefix)
+               public ICollection CompletionGetTypesStartingWith (string prefix)
                {
                        Hashtable result = new Hashtable ();
                        
@@ -1106,10 +1095,10 @@ namespace Mono.CSharp {
                                                if (ld != -1){
                                                        string rest = prefix.Substring (ld+1);
 
-                                                       using_ns.CompletionGetTypesStartingWith (ds, rest, result);
+                                                       using_ns.CompletionGetTypesStartingWith (rest, result);
                                                }
                                        }
-                                       using_ns.CompletionGetTypesStartingWith (ds, prefix, result);
+                                       using_ns.CompletionGetTypesStartingWith (prefix, result);
                                }
                        }
 
@@ -1125,7 +1114,7 @@ namespace Mono.CSharp {
                }
 
                // Looks-up a alias named @name in this and surrounding namespace declarations
-               public FullNamedExpression LookupAlias (string name)
+               public FullNamedExpression LookupNamespaceAlias (string name)
                {
                        for (NamespaceEntry n = this; n != null; n = n.ImplicitParent) {
                                if (n.using_aliases == null)
@@ -1140,12 +1129,12 @@ namespace Mono.CSharp {
                        return null;
                }
 
-               private FullNamedExpression Lookup (DeclSpace ds, string name, Location loc, bool ignore_cs0104)
+               private FullNamedExpression Lookup (string name, Location loc, bool ignore_cs0104)
                {
                        //
                        // Check whether it's in the namespace.
                        //
-                       FullNamedExpression fne = ns.Lookup (ds, name, loc);
+                       FullNamedExpression fne = ns.Lookup (name, loc);
 
                        //
                        // Check aliases. 
@@ -1182,7 +1171,7 @@ namespace Mono.CSharp {
                        //
                        FullNamedExpression match = null;
                        foreach (Namespace using_ns in GetUsingTable ()) {
-                               match = using_ns.Lookup (ds, name, loc);
+                               match = using_ns.Lookup (name, loc);
                                if (match == null || !(match is TypeExpr))
                                        continue;
                                if (fne != null) {
@@ -1322,6 +1311,18 @@ namespace Mono.CSharp {
 
                #region IResolveContext Members
 
+               public Type CurrentType {
+                       get { return SlaveDeclSpace.CurrentType; }
+               }
+
+               public TypeContainer CurrentTypeDefinition {
+                       get { return SlaveDeclSpace.CurrentTypeDefinition; }
+               }
+
+               public TypeParameter[] CurrentTypeParameters {
+                       get { return SlaveDeclSpace.CurrentTypeParameters; }
+               }
+
                public DeclSpace DeclContainer {
                        get { return SlaveDeclSpace; }
                }
@@ -1334,6 +1335,10 @@ namespace Mono.CSharp {
                        get { return SlaveDeclSpace.IsInUnsafeScope; }
                }
 
+               public bool IsStatic {
+                       get { return SlaveDeclSpace.IsStatic; }
+               }
+
                public DeclSpace GenericDeclContainer {
                        get { return SlaveDeclSpace; }
                }
index 51da6dd2410c145eb3e80350703f96b7e70b7d3d..3f29a082e2fb8052083719daca5d251989e02be2 100644 (file)
@@ -21,15 +21,10 @@ namespace Mono.CSharp {
        /// <summary>
        ///   Abstract Base class for parameters of a method.
        /// </summary>
-       public abstract class ParameterBase : Attributable {
-
+       public abstract class ParameterBase : Attributable
+       {
                protected ParameterBuilder builder;
 
-               protected ParameterBase (Attributes attrs)
-                       : base (attrs)
-               {
-               }
-
                public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
                {
 #if !NET_2_0
@@ -59,8 +54,7 @@ namespace Mono.CSharp {
        /// Class for applying custom attributes on the return type
        /// </summary>
        public class ReturnParameter : ParameterBase {
-               public ReturnParameter (MethodBuilder mb, Location location):
-                       base (null)
+               public ReturnParameter (MethodBuilder mb, Location location)
                {
                        try {
                                builder = mb.DefineParameter (0, ParameterAttributes.None, "");                 
@@ -95,12 +89,6 @@ namespace Mono.CSharp {
                                pa.EmitAttribute (builder, loc);
                }
 
-               public override IResolveContext ResolveContext {
-                       get {
-                               throw new NotSupportedException ();
-                       }
-               }
-
                /// <summary>
                /// Is never called
                /// </summary>
@@ -118,8 +106,7 @@ namespace Mono.CSharp {
        /// 
        // TODO: should use more code from Parameter.ApplyAttributeBuilder
        public class ImplicitParameter : ParameterBase {
-               public ImplicitParameter (MethodBuilder mb):
-                       base (null)
+               public ImplicitParameter (MethodBuilder mb)
                {
                        builder = mb.DefineParameter (1, ParameterAttributes.None, "value");                    
                }
@@ -130,12 +117,6 @@ namespace Mono.CSharp {
                        }
                }
 
-               public override IResolveContext ResolveContext {
-                       get {
-                               throw new NotSupportedException ();
-                       }
-               }
-
                /// <summary>
                /// Is never called
                /// </summary>
@@ -258,14 +239,12 @@ namespace Mono.CSharp {
                int idx;
                public bool HasAddressTaken;
 
-               IResolveContext resolve_context;
                LocalVariableReference expr_tree_variable;
                static TypeExpr parameter_expr_tree_type;
 
                public HoistedVariable HoistedVariableReference;
 
                public Parameter (FullNamedExpression type, string name, Modifier mod, Attributes attrs, Location loc)
-                       : base (attrs)
                {
                        if (type == TypeManager.system_void_expr)
                                Report.Error (1536, loc, "Invalid parameter type `void'");
@@ -274,6 +253,9 @@ namespace Mono.CSharp {
                        modFlags = mod;
                        Location = loc;
                        TypeName = type;
+
+                       // Only assign, attributes will be attached during resolve
+                       base.attributes = attrs;
                }
 
                public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
@@ -345,23 +327,17 @@ namespace Mono.CSharp {
                        return member.IsAccessibleAs (parameter_type);
                }
 
-               public override IResolveContext ResolveContext {
-                       get {
-                               return resolve_context;
-                       }
-               }
-
                // <summary>
                //   Resolve is used in method definitions
                // </summary>
                public virtual Type Resolve (IResolveContext rc)
                {
-                       // HACK: to resolve attributes correctly
-                       this.resolve_context = rc;
-
                        if (parameter_type != null)
                                return parameter_type;
 
+                       if (attributes != null)
+                               attributes.AttachTo (this, rc);
+
                        TypeExpr texpr = TypeName.ResolveAsTypeTerminal (rc, false);
                        if (texpr == null)
                                return null;
@@ -374,7 +350,7 @@ namespace Mono.CSharp {
                                return parameter_type;
 
                        if (default_expr != null) {
-                               EmitContext ec = new EmitContext (rc, rc.GenericDeclContainer, Location, null, parameter_type, 0);
+                               EmitContext ec = new EmitContext (rc, rc.GenericDeclContainer, null, parameter_type);
                                default_expr = default_expr.Resolve (ec);
                                if (default_expr != null) {
                                        Constant value = default_expr as Constant;
@@ -430,7 +406,7 @@ namespace Mono.CSharp {
                                (modFlags & Parameter.Modifier.ISBYREF) != 0 ? Variance.None : Variance.Contravariant,
                                rc as MemberCore);
 
-                       if (texpr is TypeParameterExpr)
+                       if (TypeManager.IsGenericParameter (parameter_type))
                                return parameter_type;
 
                        if ((parameter_type.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute) {
@@ -557,10 +533,8 @@ namespace Mono.CSharp {
                public Parameter Clone ()
                {
                        Parameter p = (Parameter) MemberwiseClone ();
-                       if (attributes != null) {
+                       if (attributes != null)
                                p.attributes = attributes.Clone ();
-                               p.attributes.AttachTo (p);
-                       }
 
                        return p;
                }
index d3c235fe93aacf2d9c8564353d7ab986a85f7359..e9d2d26bebf1cbdd38c219b296da8b2f7215ccce 100644 (file)
@@ -62,7 +62,7 @@ namespace Mono.CSharp
                public void AddAttributes (ArrayList attrs)
                {
                        foreach (Attribute a in attrs)
-                               a.AttachTo (this);
+                               a.AttachTo (this, CodeGen.Assembly);
 
                        if (attributes == null) {
                                attributes = new Attributes (attrs);
@@ -154,10 +154,6 @@ namespace Mono.CSharp
                        }
                }
 
-               public override IResolveContext ResolveContext {
-                       get { return this; }
-               }
-
                protected override bool AddMemberType (DeclSpace ds)
                {
                        if (!AddToContainer (ds, ds.Name))
@@ -264,5 +260,10 @@ namespace Mono.CSharp
                {
                        return PartialContainer.IsClsComplianceRequired ();
                }
+
+               public override FullNamedExpression LookupNamespaceAlias (string name)
+               {
+                       return NamespaceEntry.LookupNamespaceAlias (name);
+               }
        }
 }
index 880ec5670e0e9ce4d00a44c74f3bf91924097170..ef0fb06875e5cf274b9c59bca2ac46bdcfa29736 100644 (file)
@@ -736,7 +736,7 @@ namespace Mono.CSharp {
 
                public override bool Resolve (EmitContext ec)
                {
-                       if (expr != null)
+                       if (expr != null && expr.eclass == ExprClass.Invalid)
                                expr = expr.ResolveStatement (ec);
                        return expr != null;
                }
@@ -827,27 +827,21 @@ namespace Mono.CSharp {
                        if (Expr == null)
                                return false;
 
+                       if (ec.HasSet (EmitContext.Options.InferReturnType)) {
+                               ec.ReturnTypeInference.AddCommonTypeBound (Expr.Type);
+                               return true;
+                       }
+
                        if (Expr.Type != ec.ReturnType) {
-                               if (ec.InferReturnType) {
-                                       //
-                                       // void cannot be used in contextual return
-                                       //
-                                       if (Expr.Type == TypeManager.void_type)
-                                               return false;
+                               Expr = Convert.ImplicitConversionRequired (ec, Expr, ec.ReturnType, loc);
 
-                                       ec.ReturnType = Expr.Type;
-                               } else {
-                                       Expr = Convert.ImplicitConversionRequired (
-                                               ec, Expr, ec.ReturnType, loc);
-
-                                       if (Expr == null) {
-                                               if (am != null) {
-                                                       Report.Error (1662, loc,
-                                                               "Cannot convert `{0}' to delegate type `{1}' because some of the return types in the block are not implicitly convertible to the delegate return type",
-                                                               am.ContainerType, am.GetSignatureForError ());
-                                               }
-                                               return false;
+                               if (Expr == null) {
+                                       if (am != null) {
+                                               Report.Error (1662, loc,
+                                                       "Cannot convert `{0}' to delegate type `{1}' because some of the return types in the block are not implicitly convertible to the delegate return type",
+                                                       am.ContainerType, am.GetSignatureForError ());
                                        }
+                                       return false;
                                }
                        }
 
@@ -1348,7 +1342,7 @@ namespace Mono.CSharp {
                                ec.DefineLocalVariable (Name, builder);
                }
 
-               public bool IsThisAssigned (EmitContext ec)
+               public bool IsThisAssigned (EmitContext ec, Block block)
                {
                        if (VariableInfo == null)
                                throw new Exception ();
@@ -1356,7 +1350,7 @@ namespace Mono.CSharp {
                        if (!ec.DoFlowAnalysis || ec.CurrentBranching.IsAssigned (VariableInfo))
                                return true;
 
-                       return VariableInfo.TypeInfo.IsFullyInitialized (ec.CurrentBranching, VariableInfo, ec.loc);
+                       return VariableInfo.TypeInfo.IsFullyInitialized (ec.CurrentBranching, VariableInfo, block.StartLocation);
                }
 
                public bool IsAssigned (EmitContext ec)
@@ -2060,7 +2054,7 @@ namespace Mono.CSharp {
 
                                ec.CurrentBlock = this;
                                Expression e;
-                               using (ec.With (EmitContext.Flags.ConstantCheckState, (flags & Flags.Unchecked) == 0)) {
+                               using (ec.With (EmitContext.Options.ConstantCheckState, (flags & Flags.Unchecked) == 0)) {
                                        e = cv.Resolve (ec);
                                }
                                if (e == null)
@@ -2092,7 +2086,7 @@ namespace Mono.CSharp {
 
                        // If some parent block was unsafe, we remain unsafe even if this block
                        // isn't explicitly marked as such.
-                       using (ec.With (EmitContext.Flags.InUnsafe, ec.InUnsafe | Unsafe)) {
+                       using (ec.With (EmitContext.Options.UnsafeScope, ec.InUnsafe | Unsafe)) {
                                flags |= Flags.VariablesInitialized;
 
                                if (variables != null) {
@@ -2199,6 +2193,14 @@ namespace Mono.CSharp {
 
                        Report.Debug (4, "RESOLVE BLOCK", StartLocation, ec.CurrentBranching);
 
+                       //
+                       // Compiler generated scope statements
+                       //
+                       if (scope_initializers != null) {
+                               foreach (Statement s in scope_initializers)
+                                       s.Resolve (ec);
+                       }
+
                        //
                        // This flag is used to notate nested statements as unreachable from the beginning of this block.
                        // For the purposes of this resolution, it doesn't matter that the whole block is unreachable 
@@ -2330,7 +2332,7 @@ namespace Mono.CSharp {
                {
                        SymbolWriter.OpenCompilerGeneratedBlock (ec.ig);
 
-                       using (ec.Set (EmitContext.Flags.OmitDebuggingInfo)) {
+                       using (ec.Set (EmitContext.Options.OmitDebuggingInfo)) {
                                foreach (Statement s in scope_initializers)
                                        s.Emit (ec);
                        }
@@ -2477,7 +2479,7 @@ namespace Mono.CSharp {
                                //
                                // Creates anonymous method storey for this block
                                //
-                               am_storey = new AnonymousMethodStorey (this, ec.TypeContainer, mc, gm, "AnonStorey");
+                               am_storey = new AnonymousMethodStorey (this, ec.CurrentTypeDefinition, mc, gm, "AnonStorey");
                        }
 
                        return am_storey;
@@ -2636,7 +2638,6 @@ namespace Mono.CSharp {
                                if (child == null)
                                        return null;
                                
-                               block.ResolveMeta (ec, ParametersCompiled.EmptyReadOnlyParameters);
                                child = child.Resolve (ec);
                                if (child == null)
                                        return null;
@@ -2662,10 +2663,11 @@ namespace Mono.CSharp {
                }
 
                GenericMethod generic;
-               FlowBranchingToplevel top_level_branching;
                protected ParametersCompiled parameters;
                ToplevelParameterInfo[] parameter_info;
                LocalInfo this_variable;
+               bool resolved;
+               bool unreachable;
 
                public HoistedVariable HoistedThisVariable;
 
@@ -2820,10 +2822,6 @@ namespace Mono.CSharp {
                        return iterator_storey;
                }
 
-               public FlowBranchingToplevel TopLevelBranching {
-                       get { return top_level_branching; }
-               }
-
                //
                // Returns a parameter reference expression for the given name,
                // or null if there is no such parameter
@@ -2881,17 +2879,58 @@ namespace Mono.CSharp {
 
                public bool IsThisAssigned (EmitContext ec)
                {
-                       return this_variable == null || this_variable.IsThisAssigned (ec);
+                       return this_variable == null || this_variable.IsThisAssigned (ec, this);
+               }
+
+               public bool Resolve (FlowBranching parent, EmitContext rc, ParametersCompiled ip, IMethodData md)
+               {
+                       if (resolved)
+                               return true;
+
+                       resolved = true;
+
+                       try {
+                               if (!ResolveMeta (rc, ip))
+                                       return false;
+
+                               using (rc.With (EmitContext.Options.DoFlowAnalysis, true)) {
+                                       FlowBranchingToplevel top_level = rc.StartFlowBranching (this, parent);
+
+                                       if (!Resolve (rc))
+                                               return false;
+
+                                       unreachable = top_level.End ();
+                               }
+                       } catch (Exception) {
+#if PRODUCTION
+                               if (rc.CurrentBlock != null) {
+                                       Report.Error (584, rc.CurrentBlock.StartLocation, "Internal compiler error: Phase Resolve");
+                               } else {
+                                       Report.Error (587, "Internal compiler error: Phase Resolve");
+                               }
+#endif
+                               throw;
+                       }
+
+                       if (rc.ReturnType != TypeManager.void_type && !unreachable) {
+                               if (rc.CurrentAnonymousMethod == null) {
+                                       Report.Error (161, md.Location, "`{0}': not all code paths return a value", md.GetSignatureForError ());
+                                       return false;
+                               } else if (!rc.CurrentAnonymousMethod.IsIterator) {
+                                       Report.Error (1643, rc.CurrentAnonymousMethod.Location, "Not all code paths return a value in anonymous method of type `{0}'",
+                                                         rc.CurrentAnonymousMethod.GetSignatureForError ());
+                                       return false;
+                               }
+                       }
+
+                       return true;
                }
 
-               public bool ResolveMeta (EmitContext ec, ParametersCompiled ip)
+               bool ResolveMeta (EmitContext ec, ParametersCompiled ip)
                {
                        int errors = Report.Errors;
                        int orig_count = parameters.Count;
 
-                       if (top_level_branching != null)
-                               return true;
-
                        if (ip != null)
                                parameters = ip;
 
@@ -2914,8 +2953,6 @@ namespace Mono.CSharp {
 
                        ResolveMeta (ec, offset);
 
-                       top_level_branching = ec.StartFlowBranching (this);
-
                        return Report.Errors == errors;
                }
 
@@ -2943,6 +2980,61 @@ namespace Mono.CSharp {
                        }
                }
 
+               public override void Emit (EmitContext ec)
+               {
+                       if (Report.Errors > 0)
+                               return;
+
+#if PRODUCTION
+                       try {
+#endif
+                       EmitMeta (ec);
+
+                       if (ec.HasReturnLabel)
+                               ec.ReturnLabel = ec.ig.DefineLabel ();
+
+                       base.Emit (ec);
+
+                       ec.Mark (EndLocation);
+
+                       if (ec.HasReturnLabel)
+                               ec.ig.MarkLabel (ec.ReturnLabel);
+
+                       if (ec.return_value != null) {
+                               ec.ig.Emit (OpCodes.Ldloc, ec.return_value);
+                               ec.ig.Emit (OpCodes.Ret);
+                       } else {
+                               //
+                               // If `HasReturnLabel' is set, then we already emitted a
+                               // jump to the end of the method, so we must emit a `ret'
+                               // there.
+                               //
+                               // Unfortunately, System.Reflection.Emit automatically emits
+                               // a leave to the end of a finally block.  This is a problem
+                               // if no code is following the try/finally block since we may
+                               // jump to a point after the end of the method.
+                               // As a workaround, we're always creating a return label in
+                               // this case.
+                               //
+
+                               if (ec.HasReturnLabel || !unreachable) {
+                                       if (ec.ReturnType != TypeManager.void_type)
+                                               ec.ig.Emit (OpCodes.Ldloc, ec.TemporaryReturn ());
+                                       ec.ig.Emit (OpCodes.Ret);
+                               }
+                       }
+
+#if PRODUCTION
+                       } catch (Exception e){
+                               Console.WriteLine ("Exception caught by the compiler while emitting:");
+                               Console.WriteLine ("   Block that caused the problem begin at: " + block.loc);
+                                       
+                               Console.WriteLine (e.GetType ().FullName + ": " + e.Message);
+                               throw;
+                       }
+#endif
+               }
+
                public override void EmitMeta (EmitContext ec)
                {
                        parameters.ResolveVariable ();
@@ -2962,12 +3054,6 @@ namespace Mono.CSharp {
 
                        base.EmitSymbolInfo (ec);
                }
-
-               public override void Emit (EmitContext ec)
-               {
-                       base.Emit (ec);
-                       ec.Mark (EndLocation);
-               }
        }
        
        public class SwitchLabel {
@@ -3708,12 +3794,12 @@ namespace Mono.CSharp {
                                string_dictionary_type = new MemberAccess (system_collections_generic, "Hashtable", loc);
                        }
 
-                       Field field = new Field (ec.TypeContainer, string_dictionary_type,
+                       Field field = new Field (ec.CurrentTypeDefinition, string_dictionary_type,
                                Modifiers.STATIC | Modifiers.PRIVATE | Modifiers.COMPILER_GENERATED,
                                new MemberName (CompilerGeneratedClass.MakeName (null, "f", "switch$map", unique_counter++), loc), null);
                        if (!field.Define ())
                                return;
-                       ec.TypeContainer.PartialContainer.AddField (field);
+                       ec.CurrentTypeDefinition.PartialContainer.AddField (field);
 
                        ArrayList init = new ArrayList ();
                        int counter = 0;
@@ -4151,13 +4237,13 @@ namespace Mono.CSharp {
 
                public override bool Resolve (EmitContext ec)
                {
-                       using (ec.With (EmitContext.Flags.AllCheckStateFlags, false))
+                       using (ec.With (EmitContext.Options.AllCheckStateFlags, false))
                                return Block.Resolve (ec);
                }
                
                protected override void DoEmit (EmitContext ec)
                {
-                       using (ec.With (EmitContext.Flags.AllCheckStateFlags, false))
+                       using (ec.With (EmitContext.Options.AllCheckStateFlags, false))
                                Block.Emit (ec);
                }
 
@@ -4185,13 +4271,13 @@ namespace Mono.CSharp {
 
                public override bool Resolve (EmitContext ec)
                {
-                       using (ec.With (EmitContext.Flags.AllCheckStateFlags, true))
+                       using (ec.With (EmitContext.Options.AllCheckStateFlags, true))
                                return Block.Resolve (ec);
                }
 
                protected override void DoEmit (EmitContext ec)
                {
-                       using (ec.With (EmitContext.Flags.AllCheckStateFlags, true))
+                       using (ec.With (EmitContext.Options.AllCheckStateFlags, true))
                                Block.Emit (ec);
                }
 
@@ -4215,17 +4301,21 @@ namespace Mono.CSharp {
                {
                        Block = b;
                        Block.Unsafe = true;
+                       loc = b.StartLocation;
                }
 
                public override bool Resolve (EmitContext ec)
                {
-                       using (ec.With (EmitContext.Flags.InUnsafe, true))
+                       if (ec.CurrentIterator != null)
+                               Report.Error (1629, loc, "Unsafe code may not appear in iterators");
+
+                       using (ec.With (EmitContext.Options.UnsafeScope, true))
                                return Block.Resolve (ec);
                }
                
                protected override void DoEmit (EmitContext ec)
                {
-                       using (ec.With (EmitContext.Flags.InUnsafe, true))
+                       using (ec.With (EmitContext.Options.UnsafeScope, true))
                                Block.Emit (ec);
                }
 
@@ -4301,29 +4391,30 @@ namespace Mono.CSharp {
                                pinned_string.Pinned = true;
                        }
 
+                       public StringEmitter Resolve (EmitContext rc)
+                       {
+                               pinned_string.Resolve (rc);
+
+                               if (TypeManager.int_get_offset_to_string_data == null) {
+                                       TypeManager.int_get_offset_to_string_data = TypeManager.GetPredefinedProperty (
+                                               TypeManager.runtime_helpers_type, "OffsetToStringData", pinned_string.Location, TypeManager.int32_type);
+                               }
+
+                               return this;
+                       }
+
                        public override void Emit (EmitContext ec)
                        {
-                               pinned_string.Resolve (ec);
                                pinned_string.ResolveVariable (ec);
 
                                converted.Emit (ec);
                                pinned_string.EmitAssign (ec);
 
-                               PropertyInfo p = TypeManager.int_get_offset_to_string_data;
-                               if (p == null) {
-                                       // TODO: Move to resolve
-                                       p = TypeManager.int_get_offset_to_string_data = TypeManager.GetPredefinedProperty (
-                                               TypeManager.runtime_helpers_type, "OffsetToStringData", pinned_string.Location, TypeManager.int32_type);
-
-                                       if (p == null)
-                                               return;
-                               }
-
                                // TODO: Should use Binary::Add
                                pinned_string.Emit (ec);
                                ec.ig.Emit (OpCodes.Conv_I);
 
-                               PropertyExpr pe = new PropertyExpr (pinned_string.VariableType, p, pinned_string.Location);
+                               PropertyExpr pe = new PropertyExpr (pinned_string.VariableType, TypeManager.int_get_offset_to_string_data, pinned_string.Location);
                                //pe.InstanceExpression = pinned_string;
                                pe.Resolve (ec).Emit (ec);
 
@@ -4398,9 +4489,10 @@ namespace Mono.CSharp {
                                        return false;
                                }
 
-                               ec.InFixedInitializer = true;
-                               e = e.Resolve (ec);
-                               ec.InFixedInitializer = false;
+                               using (ec.Set (EmitContext.Options.FixedInitializerScope)) {
+                                       e = e.Resolve (ec);
+                               }
+
                                if (e == null)
                                        return false;
 
@@ -4448,7 +4540,7 @@ namespace Mono.CSharp {
                                // Case 3: string
                                //
                                if (e.Type == TypeManager.string_type){
-                                       data [i] = new StringEmitter (e, vi, loc);
+                                       data [i] = new StringEmitter (e, vi, loc).Resolve (ec);
                                        i++;
                                        continue;
                                }
@@ -4598,7 +4690,7 @@ namespace Mono.CSharp {
 
                public override bool Resolve (EmitContext ec)
                {
-                       using (ec.With (EmitContext.Flags.InCatch, true)) {
+                       using (ec.With (EmitContext.Options.CatchScope, true)) {
                                if (type_expr != null) {
                                        TypeExpr te = type_expr.ResolveAsTypeTerminal (ec, false);
                                        if (te == null)
@@ -4668,7 +4760,7 @@ namespace Mono.CSharp {
 
                        if (ok)
                                ec.CurrentBranching.CreateSibling (fini, FlowBranching.SiblingType.Finally);
-                       using (ec.With (EmitContext.Flags.InFinally, true)) {
+                       using (ec.With (EmitContext.Options.FinallyScope, true)) {
                                if (!fini.Resolve (ec))
                                        ok = false;
                        }
@@ -4925,7 +5017,7 @@ namespace Mono.CSharp {
                        }
 
                        Expression ml = Expression.MemberLookup (
-                               ec.ContainerType, TypeManager.idisposable_type, expr_type,
+                               ec.CurrentType, TypeManager.idisposable_type, expr_type,
                                "Dispose", Location.Null);
 
                        if (!(ml is MethodGroupExpr)) {
@@ -5403,7 +5495,7 @@ namespace Mono.CSharp {
                                                enumerator_type = return_type;
                                                if (!FetchGetCurrent (ec, return_type))
                                                        get_current = new PropertyExpr (
-                                                               ec.ContainerType, TypeManager.ienumerator_getcurrent, loc);
+                                                               ec.CurrentType, TypeManager.ienumerator_getcurrent, loc);
                                                if (!FetchMoveNext (return_type))
                                                        move_next = TypeManager.bool_movenext_void;
                                                return true;
@@ -5415,7 +5507,7 @@ namespace Mono.CSharp {
                                                enumerator_type = return_type;
                                                move_next = TypeManager.bool_movenext_void;
                                                get_current = new PropertyExpr (
-                                                       ec.ContainerType, TypeManager.ienumerator_getcurrent, loc);
+                                                       ec.CurrentType, TypeManager.ienumerator_getcurrent, loc);
                                                return true;
                                        }
                                } else {
@@ -5465,7 +5557,7 @@ namespace Mono.CSharp {
                        bool FetchGetCurrent (EmitContext ec, Type t)
                        {
                                PropertyExpr pe = Expression.MemberLookup (
-                                       ec.ContainerType, t, "Current", MemberTypes.Property,
+                                       ec.CurrentType, t, "Current", MemberTypes.Property,
                                        Expression.AllBindingFlags, loc) as PropertyExpr;
                                if (pe == null)
                                        return false;
@@ -5501,7 +5593,7 @@ namespace Mono.CSharp {
                        bool TryType (EmitContext ec, Type t)
                        {
                                MethodGroupExpr mg = Expression.MemberLookup (
-                                       ec.ContainerType, t, "GetEnumerator", MemberTypes.Method,
+                                       ec.CurrentType, t, "GetEnumerator", MemberTypes.Method,
                                        Expression.AllBindingFlags, loc) as MethodGroupExpr;
                                if (mg == null)
                                        return false;
index 47dec4b23bcfea2fe30c674e03caa52fa9368549..249fdfdb8775b016a699597079336026f5887c74 100644 (file)
@@ -787,7 +787,7 @@ namespace Mono.CSharp {
        public static Type CoreLookupType (string ns_name, string name, Kind type_kind, bool required)
        {
                Namespace ns = GlobalRootNamespace.Instance.GetNamespace (ns_name, true);
-               Expression expr = ns.Lookup (RootContext.ToplevelTypes, name, Location.Null);
+               Expression expr = ns.Lookup (name, Location.Null);
 
                if (expr == null) {
                        if (required) {
diff --git a/mcs/tests/gtest-456.cs b/mcs/tests/gtest-456.cs
new file mode 100644 (file)
index 0000000..93c9b41
--- /dev/null
@@ -0,0 +1,24 @@
+using System;
+
+class G<T>
+{
+       public struct S
+       {
+               public string Test ()
+               {
+                       return GetType ().ToString ();
+               }
+       }
+}
+
+class C
+{      
+       public static int Main ()
+       {
+               string s = new G<int>.S ().Test ();
+               if (s != "G`1+S[System.Int32]")
+                       return 1;
+
+               return 0;
+       }
+}
diff --git a/mcs/tests/gtest-lambda-23.cs b/mcs/tests/gtest-lambda-23.cs
new file mode 100644 (file)
index 0000000..dded095
--- /dev/null
@@ -0,0 +1,19 @@
+using System;
+
+class C
+{
+       static U Test<T, U>(T[] args, Func<T, U> f)
+       {
+               return f (args [1]);
+       }
+
+       public static int Main ()
+       {
+               var s = new string [] { "aaa", "bbb" };
+               var foo = Test (s, i => { try { return i; } catch { return null; } });
+               if (foo != s [1])
+                       return 1;
+
+               return 0;
+       }
+}
diff --git a/mcs/tests/gtest-partial-01.cs b/mcs/tests/gtest-partial-01.cs
new file mode 100644 (file)
index 0000000..86be170
--- /dev/null
@@ -0,0 +1,22 @@
+using System;
+
+class B<U>
+{
+}
+
+partial class C<T> : B<T>
+{
+       T t1;
+}
+
+partial class C<T> : B<T>
+{
+       T t2;
+}
+
+class Test
+{
+       public static void Main ()
+       {
+       }
+}
index 6d9c791ce185f5596e9dafa14f50247e84385a1a..cb882007483ed030447814ed253c603262c642ca 100644 (file)
@@ -22,4 +22,5 @@ gtest-variance-12.cs
 
 test-416.cs bug #504085
 test-418.cs bug #504085
+test-682.cs bug #530861
 test-704.cs IGNORE #472845
index 6d9c791ce185f5596e9dafa14f50247e84385a1a..cb882007483ed030447814ed253c603262c642ca 100644 (file)
@@ -22,4 +22,5 @@ gtest-variance-12.cs
 
 test-416.cs bug #504085
 test-418.cs bug #504085
+test-682.cs bug #530861
 test-704.cs IGNORE #472845
index e9752bff6f422b87fa3fc1bb5d2e3218617d3f4b..d75032d6623e5aa27df9e010c74df87ca69ff7d8 100644 (file)
@@ -5,4 +5,5 @@
 # csXXXX.cs IGNORE     : adds test to ignore list
 
 test-xml-027.cs
+test-682.cs Bug #530861
 test-704.cs IGNORE #472845
index 0280bf416a07a65f4ac1d7c8215000989e890f26..218a6958ec358bd1dcae42c17c98b3d225103d6c 100644 (file)
       <method name="Void .ctor()">
         <size>7</size>
       </method>
-      <method name="Int32 SetEnum(System.String, Enum)">
-        <size>2</size>
-      </method>
-      <method name="Int32 SetEnum(Int32, Enum)">
-        <size>2</size>
-      </method>
     </type>
     <type name="Test">
       <method name="Void .ctor()">
         <size>31</size>
       </method>
     </type>
+    <type name="TestThing">
+      <method name="Int32 SetEnum(System.String, System.Enum)">
+        <size>2</size>
+      </method>
+      <method name="Int32 SetEnum(Int32, System.Enum)">
+        <size>2</size>
+      </method>
+    </type>
   </test>
   <test name="gtest-352.cs">
     <type name="T">
       </method>
     </type>
   </test>
+  <test name="gtest-456.cs">
+    <type name="G`1[T]">
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="G`1+S[T]">
+      <method name="System.String Test()">
+        <size>22</size>
+      </method>
+    </type>
+    <type name="C">
+      <method name="Int32 Main()">
+        <size>36</size>
+      </method>
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="gtest-anon-1.cs">
     <type name="X">
       <method name="Void .ctor()">
       </method>
     </type>
   </test>
+  <test name="gtest-lambda-23.cs">
+    <type name="C">
+      <method name="U Test[T,U](T[], System.Func`2[T,U])">
+        <size>14</size>
+      </method>
+      <method name="Int32 Main()">
+        <size>77</size>
+      </method>
+      <method name="System.String &lt;Main&gt;m__0(System.String)">
+        <size>27</size>
+      </method>
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="gtest-linq-01.cs">
     <type name="from.C">
       <method name="Void .ctor()">
       </method>
     </type>
   </test>
+  <test name="gtest-partial-01.cs">
+    <type name="B`1[U]">
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="C`1[T]">
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="Test">
+      <method name="Void Main()">
+        <size>1</size>
+      </method>
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="gtest-var-04.cs">
     <type name="Test">
       <method name="Void .ctor()">
       <method name="Void .ctor()">
         <size>7</size>
       </method>
-      <method name="Boolean EnumInSet(Enum, System.Enum[])">
-        <size>37</size>
-      </method>
       <method name="Void Main()">
         <size>1</size>
       </method>
+      <method name="Boolean EnumInSet(System.Enum, System.Enum[])">
+        <size>37</size>
+      </method>
     </type>
   </test>
   <test name="test-281.cs">
       <method name="System.Object get_Val()">
         <size>7</size>
       </method>
-      <method name="Enum get_Val2()">
+      <method name="System.Enum get_Val2()">
         <size>7</size>
       </method>
     </type>
index 332cacc2ccf071d603484d72f32334209fba3db8..9c24478e50286891bd912df9e33acd2cdee7e809 100644 (file)
@@ -1,3 +1,16 @@
+2009-08-12  Jonathan Pryor <jpryor@novell.com>
+
+       * Test/DocTest-v1.cs: Add a comment which uses <format/>, to test html
+         escaping behavior.
+       * Resources/monodoc-ecma.xsd: Permit <format/> in various elements.
+       * Test/en.expected.importslashdoc/Mono.DocTest/DocAttribute.xml,
+         Test/html.expected/Mono.DocTest/DocAttribute.html,
+         Test/msxdoc-expected.importslashdoc.xml: Flush.
+
+2009-08-12  Jonathan Pryor <jpryor@novell.com>
+
+       * Makefile: Add ../monodoc/Resources/mdoc-html-format.xsl as a resource.
+
 2009-08-06  Jonathan Pryor <jpryor@novell.com>
 
        * mdoc.exe.sources: Add ../../build/common/Consts.cs to the build.
index 9ec57e1514a740430837c68863e1add8b8d4181f..576afc644d0479456e90d45a50c1b5e3c9cbf797 100644 (file)
@@ -3,6 +3,7 @@ SUBDIRS =
 include ../../build/rules.make
 
 LOCAL_MCS_FLAGS = \
+       /resource:../monodoc/Resources/mdoc-html-format.xsl,mdoc-html-format.xsl    \
        /resource:../monodoc/Resources/mdoc-html-utils.xsl,mdoc-html-utils.xsl      \
        /resource:../monodoc/Resources/mdoc-sections-css.xsl,mdoc-sections-css.xsl  \
        /resource:../monodoc/Resources/mono-ecma-css.xsl,mono-ecma-css.xsl          \
index ffe30163e4728439e83e32da956aa5c2b7edb4ac..a9a2c73c74b944f4b18d6162f5fe067e5b1f56a7 100644 (file)
@@ -143,6 +143,7 @@ add masterdoc support?
         <xs:element ref="block" />
         <xs:element ref="c" />
         <xs:element ref="code" />
+        <xs:element ref="format" />
         <xs:element ref="list" />
         <xs:element ref="para" />
         <xs:element ref="paramref" />
@@ -277,6 +278,7 @@ add masterdoc support?
   <xs:element name="example">
     <xs:complexType mixed="true">
       <xs:choice maxOccurs="unbounded">
+        <xs:element ref="format" />
         <xs:element ref="para" />
         <xs:element ref="code" />
         <xs:element ref="c" />
@@ -290,6 +292,7 @@ add masterdoc support?
     <xs:complexType mixed="true">
       <xs:choice minOccurs="0" maxOccurs="unbounded">
         <xs:element ref="block" />
+        <xs:element ref="format" />
         <xs:element ref="para" />
         <xs:element ref="paramref" />
         <xs:element ref="see" />
@@ -307,6 +310,15 @@ add masterdoc support?
     </xs:complexType>
   </xs:element>
 
+  <xs:element name="format">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:any minOccurs="0" processContents="lax" />
+      </xs:sequence>
+      <xs:attribute ref="type" />
+    </xs:complexType>
+  </xs:element>
+
   <xs:element name="interface">
     <xs:complexType>
       <xs:choice minOccurs="0" maxOccurs="unbounded">
@@ -472,6 +484,7 @@ add masterdoc support?
     <xs:complexType mixed="true">
       <xs:choice minOccurs="0" maxOccurs="unbounded">
         <xs:element ref="block" />
+        <xs:element ref="format" />
         <xs:element ref="see" />
         <xs:element ref="list" />
         <xs:element ref="link" />
@@ -491,6 +504,7 @@ add masterdoc support?
     <xs:complexType mixed="true">
       <xs:choice minOccurs="0" maxOccurs="unbounded">
         <xs:element ref="c" />
+        <xs:element ref="format" />
         <xs:element ref="see" />
         <xs:element ref="block" />
         <xs:element ref="paramref" />
@@ -531,6 +545,7 @@ add masterdoc support?
     <xs:complexType mixed="true">
       <xs:choice minOccurs="0" maxOccurs="unbounded">
         <xs:element ref="block" />
+        <xs:element ref="format" />
         <xs:element ref="para" />
         <xs:element ref="paramref" />
         <xs:element ref="see" />
@@ -554,6 +569,7 @@ add masterdoc support?
         <xs:element ref="block" />
         <xs:element ref="c" />
         <xs:element ref="code" />
+        <xs:element ref="format" />
         <xs:element ref="para" />
         <xs:element ref="paramref" />
         <xs:element ref="see" />
@@ -569,6 +585,7 @@ add masterdoc support?
   <xs:element name="returns">
     <xs:complexType mixed="true">
       <xs:choice minOccurs="0" maxOccurs="unbounded">
+        <xs:element ref="format" />
         <xs:element ref="list" />
         <xs:element ref="para" />
         <xs:element ref="paramref" />
@@ -606,6 +623,7 @@ add masterdoc support?
     <xs:complexType mixed="true">
       <xs:choice minOccurs="0" maxOccurs="unbounded">
         <xs:element ref="block" />
+        <xs:element ref="format" />
         <xs:element ref="para" />
         <xs:element ref="paramref" />
         <xs:element ref="see" />
@@ -652,6 +670,7 @@ add masterdoc support?
       <xs:choice minOccurs="0" maxOccurs="unbounded">
         <xs:element ref="block" />
         <xs:element ref="c" />
+        <xs:element ref="format" />
         <xs:element ref="para" />
         <xs:element ref="paramref" />
         <xs:element ref="see" />
@@ -676,6 +695,7 @@ add masterdoc support?
         <xs:choice minOccurs="0" maxOccurs="unbounded">
           <xs:element ref="block" />
           <xs:element ref="c" />
+          <xs:element ref="format" />
           <xs:element ref="see" />
           <xs:element ref="para"  />
           <xs:element ref="paramref" />
@@ -748,6 +768,7 @@ add masterdoc support?
       <xs:choice minOccurs="0" maxOccurs="unbounded">
         <xs:element ref="block" />
         <xs:element ref="c" />
+        <xs:element ref="format" />
         <xs:element ref="para" />
         <xs:element ref="paramref" />
         <xs:element ref="see" />
index 773badf887baeba386bab896b7776ca5bc3a2ba0..4b622ed8d05a622fb69de3aa3fcb6f8320fc9e1a 100644 (file)
@@ -68,6 +68,15 @@ namespace Mono.DocTest {
        ///  <para>
        ///   cref=<c>T:Mono.DocTest.DocAttribute</c>.
        ///  </para>
+       ///  <format type="text/html">
+       ///   <table width="100%">
+       ///     <tr>
+       ///       <td style="color:red">red</td>
+       ///       <td style="color:blue">blue</td>
+       ///       <td style="color:green">green</td>
+       ///     </tr>
+       ///   </table>
+       ///  </format>
        ///  <code lang="C#" src="../DocTest.cs#DocAttribute Example" />
        /// </remarks>
        [AttributeUsage (AttributeTargets.All)]
index ed36e6429e5f967876ee8ed8a293b8ae471ef16b..7a228704d5b95bcbb99d75a1110cadf005897b8c 100644 (file)
       <para>
             cref=<c>T:Mono.DocTest.DocAttribute</c>.
             </para>
+      <format type="text/html">
+        <table width="100%">
+          <tr>
+            <td style="color:red">red</td>
+            <td style="color:blue">blue</td>
+            <td style="color:green">green</td>
+          </tr>
+        </table>
+      </format>
       <code lang="C#" src="../DocTest.cs#DocAttribute Example">[Doc ("documented class")]
 class Example {
        [Doc ("documented field")] public string field;
index 11f76a063651e9383c927ea5aa40be5b4e3ed7e3..d9f57f3fd78d1da0684ccb558ecd6b55ba38c48a 100644 (file)
         <p>
             cref=<tt>T:Mono.DocTest.DocAttribute</tt>.
             </p>
+        <table width="100%">
+          <tr>
+            <td style="color:red">red</td>
+            <td style="color:blue">blue</td>
+            <td style="color:green">green</td>
+          </tr>
+        </table>
         <table class="CodeExampleTable">
           <tr>
             <td>
index bcdbfaf6f68d0f598e515c9918322f43c1ee1cde..a9712b84ff0b9186ffe0339b0fed14a9ee9d51f5 100644 (file)
                 <para>
             cref=<c>T:Mono.DocTest.DocAttribute</c>.
             </para>
+                <format type="text/html">
+                    <table width="100%">
+                        <tr>
+                            <td style="color:red">red</td>
+                            <td style="color:blue">blue</td>
+                            <td style="color:green">green</td>
+                        </tr>
+                    </table>
+                </format>
                 <code lang="C#" src="../DocTest.cs#DocAttribute Example">[Doc ("documented class")]
 class Example {
        [Doc ("documented field")] public string field;
index 2ee427ade03c3897bd94bf7e8982af3eb1411b6f..022043129ef820b9e595abe2719775bf7289d0a7 100644 (file)
@@ -1,3 +1,49 @@
+2009-08-13  Jonathan Pryor  <jpryor@novell.com>
+
+       * Monodoc/provider.cs: Add a RootTree.AddSource(string) method, so that 
+         additional directories can be checked for .source file loading.
+
+2009-08-13  Jonathan Pryor  <jpryor@novell.com>
+
+       * Monodoc/provider.cs: Make RootTree.LoadTree() just call
+         RootTree.LoadTree(null), and move the .config-file parsing into
+         .LoadTree(string) (for when basedir==null).  This will simplify the
+         logic of monodoc, as we want to add the ability to monodoc to use
+         any arbitrary directory, and this will remove the need to do 
+         `if (d==null) RootTree.LoadTree(); else RootTree.LoadTree(d)`.
+         This also conforms to FxDG guidelines.
+
+2009-08-12  Jonathan Pryor  <jpryor@novell.com>
+
+       * Resources/mdoc-html-format: Added; XSLT file to match
+         "//format[@type='text/html']//*", to support "pass-through"
+         semantics.  This allows you to use actual HTML within your
+         documentation and have it visible to HTML-supporting output formats.
+         WARNING: Use as a "last resort" -- this is primarily intended for
+         importing existing HTML w/o needing lots of extra logic to convert
+         into mdoc format XML first (with a corresponding loss of fidelity).
+         However, it means that if (when) we get non-HTML output format
+         support, the <format type="text/html" /> blocks WILL be skipped for
+         that non-HTML output format.
+
+         For example, the forever-on-the-back-burner ROFF output support --
+         to remove the use of lynx, as no one ever has it installed --
+         wouldn't be able to support HTML format, so it would skip these
+         <format type="text/html"/> blocks.
+
+         Consider <format /> the moral equivalent of Perl POD's 
+         '=begin formatname' block; see perlpod(1).
+       * Resources/mdoc-html-utils.xsl: <xsl:import/> mdoc-html-format.xsl.
+         It *must* be imported (NOT included) so that it will have a lower
+         priority than other <template/>s, thus allowing the HTML formatter
+         to <xsl:apply-templates/> which then use the "normal" rules.  This
+         allows:
+               <format type="text/html">
+                       <p><see cref="T:System.String" /></p>
+               </format>
+         to work as expected.
+       * Makefile: Add mdoc-html-format.xsl as a resource.
+
 2009-04-16  Jonathan Pryor  <jpryor@novell.com>
 
        * Monodoc/man-provider.cs: NEVER return a non-null string from
index cffa79d10609936a25fbcb8553a449d1ab900957..56a09ea44b9d34a7ce5fd9689da046e9f2198477 100644 (file)
@@ -14,6 +14,7 @@ RESOURCE_FILES = \
        Resources/home.html               \
        Resources/Lminus.gif              \
        Resources/Lplus.gif               \
+       Resources/mdoc-html-format.xsl    \
        Resources/mdoc-html-utils.xsl     \
        Resources/mdoc-sections-css.xsl   \
        Resources/mdoc-sections.xsl       \
@@ -50,6 +51,7 @@ LIB_MCS_FLAGS = \
        /resource:Resources/home.html,home.html                           \
        /resource:Resources/Lminus.gif,Lminus.gif                         \
        /resource:Resources/Lplus.gif,Lplus.gif                           \
+       /resource:Resources/mdoc-html-format.xsl,mdoc-html-format.xsl     \
        /resource:Resources/mdoc-html-utils.xsl,mdoc-html-utils.xsl       \
        /resource:Resources/mdoc-sections-css.xsl,mdoc-sections-css.xsl   \
        /resource:Resources/mdoc-sections.xsl,mdoc-sections.xsl           \
index 02c0307490ad4ea966e1901628a6b6ea8ed66206..91ee1d0cdb128917293dcf0a30f72c0482aa20ec 100644 (file)
@@ -848,19 +848,7 @@ public class RootTree : Tree {
        
        public static RootTree LoadTree ()
        {
-               string basedir;
-               string myPath = System.Reflection.Assembly.GetExecutingAssembly ().Location;
-               string cfgFile = myPath + ".config";
-               if (!File.Exists (cfgFile)) {
-                       basedir = ".";
-                       return LoadTree (basedir);
-               }
-               
-               XmlDocument d = new XmlDocument ();
-               d.Load (cfgFile);
-               basedir = d.SelectSingleNode ("config/path").Attributes ["docsPath"].Value;
-               
-               return LoadTree (basedir);
+               return LoadTree (null);
        }
        
        //
@@ -868,6 +856,18 @@ public class RootTree : Tree {
        //
        public static RootTree LoadTree (string basedir)
        {
+               if (basedir == null) {
+                       string myPath = System.Reflection.Assembly.GetExecutingAssembly ().Location;
+                       string cfgFile = myPath + ".config";
+                       if (!File.Exists (cfgFile)) {
+                               basedir = ".";
+                       }
+                       else {
+                               XmlDocument d = new XmlDocument ();
+                               d.Load (cfgFile);
+                               basedir = d.SelectSingleNode ("config/path").Attributes ["docsPath"].Value;
+                       }
+               }
                XmlDocument doc = new XmlDocument ();
 
                RootTree root = new RootTree ();
@@ -893,14 +893,40 @@ public class RootTree : Tree {
                //
                // Load the sources
                //
-               string sources_dir = Path.Combine (basedir, "sources");
+               root.AddSource (Path.Combine (basedir, "sources"));
                
+               foreach (string path in UncompiledHelpSources) {
+                       EcmaUncompiledHelpSource hs = new EcmaUncompiledHelpSource(path);
+                       hs.RootTree = root;
+                       root.help_sources.Add (hs);
+                       string epath = "extra-help-source-" + hs.Name;
+                       Node hsn = root.CreateNode (hs.Name, "root:/" + epath);
+                       root.name_to_hs [epath] = hs;
+                       hsn.EnsureNodes ();
+                       foreach (Node n in hs.Tree.Nodes){
+                               hsn.AddNode (n);
+                       }
+               }
+               
+               // Clean the tree
+               PurgeNode(root);
+
+               root.Sort ();
+
+               return root;
+       }
+
+       public void AddSource (string sources_dir)
+       {
+               Node third_party = LookupEntryPoint ("various") ?? this;
+
                string [] files = Directory.GetFiles (sources_dir);
+
                foreach (string file in files){
                        if (!file.EndsWith (".source"))
                                continue;
 
-                       doc = new XmlDocument ();
+                       XmlDocument doc = new XmlDocument ();
                        try {
                                doc.Load (file);
                        } catch {
@@ -910,7 +936,7 @@ public class RootTree : Tree {
 
                        XmlNodeList extra_nodes = doc.SelectNodes ("/monodoc/node");
                        if (extra_nodes.Count > 0)
-                               root.Populate (third_party, extra_nodes);
+                               Populate (third_party, extra_nodes);
 
                        XmlNodeList sources = doc.SelectNodes ("/monodoc/source");
                        if (sources == null){
@@ -941,11 +967,11 @@ public class RootTree : Tree {
                                HelpSource hs = GetHelpSource (provider, basefilepath);
                                if (hs == null)
                                        continue;
-                               hs.RootTree = root;
-                               root.help_sources.Add (hs);
-                               root.name_to_hs [path] = hs;
+                               hs.RootTree = this;
+                               help_sources.Add (hs);
+                               name_to_hs [path] = hs;
 
-                               Node parent = root.LookupEntryPoint (path);
+                               Node parent = LookupEntryPoint (path);
                                if (parent == null){
                                        Console.Error.WriteLine ("node `{0}' is not defined on the documentation map", path);
                                        parent = third_party;
@@ -957,26 +983,6 @@ public class RootTree : Tree {
                                parent.Sort ();
                        }
                }
-               
-               foreach (string path in UncompiledHelpSources) {
-                       EcmaUncompiledHelpSource hs = new EcmaUncompiledHelpSource(path);
-                       hs.RootTree = root;
-                       root.help_sources.Add (hs);
-                       string epath = "extra-help-source-" + hs.Name;
-                       Node hsn = root.CreateNode (hs.Name, "root:/" + epath);
-                       root.name_to_hs [epath] = hs;
-                       hsn.EnsureNodes ();
-                       foreach (Node n in hs.Tree.Nodes){
-                               hsn.AddNode (n);
-                       }
-               }
-               
-               // Clean the tree
-               PurgeNode(root);
-
-               root.Sort ();
-
-               return root;
        }
        
        // Delete nodes which does not have documentaiton (source)
diff --git a/mcs/tools/monodoc/Resources/mdoc-html-format.xsl b/mcs/tools/monodoc/Resources/mdoc-html-format.xsl
new file mode 100644 (file)
index 0000000..10acd9c
--- /dev/null
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+
+<!--
+       mdoc-html-format.xsl: HTML pass-through formatting support
+
+       Author: Jonathan Pryor (jpryor@novell.com)
+
+-->
+
+<xsl:stylesheet
+       version="1.0"
+       xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+       >
+
+       <!-- pass-through any other elements unchanged - they may be HTML -->
+       <xsl:template match="//format[@type='text/html']//*">
+               <xsl:copy>
+                       <xsl:copy-of select="@*" />
+                       <xsl:apply-templates select="*|node()" />
+               </xsl:copy>
+       </xsl:template>
+
+</xsl:stylesheet>
+
index 72d2c9554e2d0dbf61746d0da290d8a96d4ae94a..7bb26d9cfabea833326e663bbe1706a571315f99 100644 (file)
@@ -24,6 +24,7 @@
        version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        >
+       <xsl:import href="mdoc-html-format.xsl" />
        
        <!-- TEMPLATE PARAMETERS -->
        <xsl:param name="language" select="'C#'"/>
index e6276385c583387c3389362311a761757c4c026e..e96b040110efbc1d805881fa535a240848587f06 100644 (file)
@@ -1,3 +1,16 @@
+2009-08-10  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * MoonlightChannelBaseExtension.cs : fixed a couple of generated
+         code to compile on .NET (not in mcs yet; some nested generics bug).
+
+2009-08-10  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * Driver.cs, CommandLineOptions.cs : add moonlight proxy generator
+         support.
+       * MoonlightChannelBaseExtension.cs : new, moonlight proxy generator.
+         Implemented as I[Service|Operation]ContractGenerationExtension.
+       * svcutil.exe.sources : add above.
+
 2006-10-19  Ankit Jain  <jankit@novell.com>
 
        * Driver.cs: Try to use HTTP GET to get wsdl, if it fails then try
index e748a60dcb98b180b57ac6c7b4e6ada6a4a91907..1b1e0ccba31317deacb79aea6c14f06e03e3667e 100644 (file)
@@ -59,6 +59,19 @@ namespace Mono.ServiceContractTool
                [Option ("Generate typed messages.", "typedMessage", "tm")]
                public bool GenerateTypedMessages;
 
+               bool generate_moonlight_proxy;
+
+               [Option ("Generate moonlight client. (This option may vanish.)", "moonlight")]
+               public bool GenerateMoonlightProxy {
+                       get { return generate_moonlight_proxy; }
+                       set {
+                               if (!value)
+                                       return;
+                               generate_moonlight_proxy = true;
+                               GenerateAsync = true;
+                       }
+               }
+
                [Option ("Generate types as internal.", 'i', "internal")]
                public bool GenerateTypesAsInternal;
 
index af22f105696030c74efe96dc4b3b2dac3e5d9f26..d365aca1a6dfdb0718ebe0d3ee2606604e0aedf8 100644 (file)
@@ -6,6 +6,7 @@ using System.Reflection;
 using System.ServiceModel;
 using System.ServiceModel.Channels;
 using System.ServiceModel.Description;
+using System.ServiceModel.Dispatcher;
 using System.Collections.ObjectModel;
 using System.Xml;
 using System.Xml.Schema;
@@ -92,8 +93,18 @@ namespace Mono.ServiceContractTool
                                generator.GenerateServiceContractType (se.Contract);*/
 
                        Collection<ContractDescription> contracts = importer.ImportAllContracts ();
-                       foreach (ContractDescription cd in contracts)
-                               generator.GenerateServiceContractType (cd);
+                       foreach (ContractDescription cd in contracts) {
+                               if (co.GenerateMoonlightProxy) {
+                                       var moonctx = new MoonlightChannelBaseContext ();
+                                       cd.Behaviors.Add (new MoonlightChannelBaseContractExtension (moonctx));
+                                       foreach (var od in cd.Operations)
+                                               od.Behaviors.Add (new MoonlightChannelBaseOperationExtension (moonctx));
+                                       generator.GenerateServiceContractType (cd);
+                                       moonctx.Fixup ();
+                               }
+                               else
+                                       generator.GenerateServiceContractType (cd);
+                       }
 
                        /*if (cns.Types.Count == 0) {
                                Console.Error.WriteLine ("Argument assemblies have no types.");
diff --git a/mcs/tools/svcutil/MoonlightChannelBaseExtension.cs b/mcs/tools/svcutil/MoonlightChannelBaseExtension.cs
new file mode 100644 (file)
index 0000000..8a99a6e
--- /dev/null
@@ -0,0 +1,289 @@
+//
+// MoonlightChannelBaseExtension.cs
+//
+// Author:
+//     Atsushi Enomoto <atsushi@ximian.com>
+//
+// Copyright (C) 2009 Novell, Inc.  http://www.novell.com
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+using System;
+using System.CodeDom;
+using System.CodeDom.Compiler;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.IO;
+using System.Reflection;
+using System.ServiceModel;
+using System.ServiceModel.Channels;
+using System.ServiceModel.Description;
+using System.ServiceModel.Dispatcher;
+
+namespace Mono.ServiceContractTool
+{
+       class MoonlightChannelBaseContext
+       {
+               public MoonlightChannelBaseContractExtension Contract;
+               public List<MoonlightChannelBaseOperationExtension> Operations = new List<MoonlightChannelBaseOperationExtension> ();
+
+               public CodeTypeDeclaration ClientType { get; set; }
+               public CodeTypeDeclaration ChannelType { get; set; }
+
+               public void FindClientType (ServiceContractGenerationContext context)
+               {
+                       var cd = context.Contract;
+                       string name = cd.Name + "Client";
+                       if (name [0] == 'I')
+                               name = name.Substring (1);
+
+                       foreach (CodeNamespace cns in context.ServiceContractGenerator.TargetCompileUnit.Namespaces)
+                               foreach (CodeTypeDeclaration ct in cns.Types)
+                                       if (ct == context.ContractType)
+                                               foreach (CodeTypeDeclaration ct2 in cns.Types)
+                                                       if (ct2.Name == name) {
+                                                               ClientType = ct2;
+                                                               return;
+                                                       }
+                       throw new Exception (String.Format ("Contract '{0}' not found", name));
+               }
+
+               public void Fixup ()
+               {
+                       Contract.Fixup ();
+                       foreach (var op in Operations)
+                               op.Fixup ();
+               }
+       }
+
+       class MoonlightChannelBaseContractExtension : IContractBehavior, IServiceContractGenerationExtension
+       {
+               public MoonlightChannelBaseContractExtension (MoonlightChannelBaseContext mlContext)
+               {
+                       ml_context = mlContext;
+               }
+
+               MoonlightChannelBaseContext ml_context;
+
+               // IContractBehavior
+               public void AddBindingParameters (ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
+               {
+                       throw new NotSupportedException ();
+               }
+
+               public void ApplyClientBehavior (
+                       ContractDescription description,
+                       ServiceEndpoint endpoint,
+                       ClientRuntime proxy)
+               {
+                       throw new NotSupportedException ();
+               }
+
+               public void ApplyDispatchBehavior (
+                       ContractDescription description,
+                       ServiceEndpoint endpoint,
+                       DispatchRuntime dispatch)
+               {
+                       throw new NotSupportedException ();
+               }
+
+               public void Validate (
+                       ContractDescription description,
+                       ServiceEndpoint endpoint)
+               {
+                       throw new NotSupportedException ();
+               }
+
+               // IServiceContractGenerationExtensions
+
+               public void GenerateContract (
+                       ServiceContractGenerationContext context)
+               {
+                       this.context = context;
+                       ml_context.Contract = this;
+               }
+
+               ServiceContractGenerationContext context;
+
+               public void Fixup ()
+               {
+                       ContractDescription cd = context.Contract;
+                       ml_context.FindClientType (context);
+                       var parentClass = ml_context.ClientType;
+
+                       string name = cd.Name + "Channel";
+                       if (name [0] == 'I')
+                               name = name.Substring (1);
+
+                       var gt = new CodeTypeReference (cd.Name);
+                       var clientBaseType = new CodeTypeReference ("System.ServiceModel.ClientBase", gt);
+                       // this omits namespace, but should compile
+                       var channelBase = new CodeTypeReference ("ChannelBase", gt);
+                       var type = new CodeTypeDeclaration (name);
+                       parentClass.Members.Add (type);
+                       type.BaseTypes.Add (channelBase);
+                       type.BaseTypes.Add (new CodeTypeReference (cd.Name));
+                       type.TypeAttributes |= TypeAttributes.NestedPrivate;
+
+                       ml_context.ChannelType = type;
+
+                       // .ctor(ClientBase<T> client)
+                       var ctor = new CodeConstructor ();
+                       ctor.Attributes = MemberAttributes.Public;
+                       ctor.Parameters.Add (
+                               new CodeParameterDeclarationExpression (
+                                       clientBaseType, "client"));
+                       ctor.BaseConstructorArgs.Add (
+                               new CodeArgumentReferenceExpression ("client"));
+                       type.Members.Add (ctor);
+               }
+       }
+
+       class MoonlightChannelBaseOperationExtension : IOperationBehavior, IOperationContractGenerationExtension
+       {
+               public MoonlightChannelBaseOperationExtension (MoonlightChannelBaseContext mlContext)
+               {
+                       ml_context = mlContext;
+               }
+
+               MoonlightChannelBaseContext ml_context;
+
+               // IOperationBehavior
+
+               public void AddBindingParameters (
+                       OperationDescription description,
+                       BindingParameterCollection parameters)
+               {
+                       throw new NotSupportedException ();
+               }
+
+               public void ApplyDispatchBehavior (
+                       OperationDescription description,
+                       DispatchOperation dispatch)
+               {
+                       throw new NotSupportedException ();
+               }
+
+               public void ApplyClientBehavior (
+                       OperationDescription description,
+                       ClientOperation proxy)
+               {
+                       throw new NotSupportedException ();
+               }
+
+               public void Validate (
+                       OperationDescription description)
+               {
+                       throw new NotSupportedException ();
+               }
+
+               // IOperationContractGenerationContext
+
+               public void GenerateOperation (OperationContractGenerationContext context)
+               {
+                       this.context = context;
+                       ml_context.Operations.Add (this);
+               }
+
+               OperationContractGenerationContext context;
+
+               public void Fixup ()
+               {
+                       var type = ml_context.ChannelType;
+                       var od = context.Operation;
+
+                       CodeMemberMethod cm = new CodeMemberMethod ();
+                       type.Members.Add (cm);
+                       cm.Name = "Begin" + od.Name;
+                       cm.Attributes = MemberAttributes.Public 
+                                       | MemberAttributes.Final;
+
+                       var inArgs = new List<CodeParameterDeclarationExpression > ();
+                       var outArgs = new List<CodeParameterDeclarationExpression > ();
+
+                       foreach (CodeParameterDeclarationExpression p in context.BeginMethod.Parameters) {
+                               inArgs.Add (p);
+                               cm.Parameters.Add (p);
+                       }
+                       inArgs.RemoveAt (inArgs.Count - 1);
+                       inArgs.RemoveAt (inArgs.Count - 1);
+
+//                     cm.Parameters.Add (new CodeParameterDeclarationExpression (new CodeTypeReference (typeof (AsyncCallback)), "asyncCallback"));
+//                     cm.Parameters.Add (new CodeParameterDeclarationExpression (new CodeTypeReference (typeof (object)), "userState"));
+                       cm.ReturnType = new CodeTypeReference (typeof (IAsyncResult));
+
+                       var argsDecl = new CodeVariableDeclarationStatement (
+                               typeof (object []),
+                               "args",
+                               new CodeArrayCreateExpression (typeof (object), inArgs.ConvertAll<CodeExpression> (decl => new CodeArgumentReferenceExpression (decl.Name)).ToArray ()));
+                       cm.Statements.Add (argsDecl);
+
+                       var args = new List<CodeExpression> ();
+                       args.Add (new CodePrimitiveExpression (od.Name));
+                       args.Add (new CodeVariableReferenceExpression ("args"));
+                       args.Add (new CodeArgumentReferenceExpression ("asyncCallback"));
+                       args.Add (new CodeArgumentReferenceExpression ("userState"));
+
+                       CodeExpression call = new CodeMethodInvokeExpression (
+                               new CodeBaseReferenceExpression (),
+                               "BeginInvoke",
+                               args.ToArray ());
+
+                       if (cm.ReturnType.BaseType == "System.Void")
+                               cm.Statements.Add (new CodeExpressionStatement (call));
+                       else
+                               cm.Statements.Add (new CodeMethodReturnStatement (call));
+
+                       // EndXxx() implementation
+
+                       cm = new CodeMemberMethod ();
+                       cm.Attributes = MemberAttributes.Public 
+                                       | MemberAttributes.Final;
+                       type.Members.Add (cm);
+                       cm.Name = "End" + od.Name;
+
+                       var res = new CodeParameterDeclarationExpression (new CodeTypeReference (typeof (IAsyncResult)), "result");
+                       cm.Parameters.Add (res);
+
+                       cm.ReturnType = context.EndMethod.ReturnType;
+
+                       string resultArgName = "result";
+                       argsDecl = new CodeVariableDeclarationStatement (
+                               typeof (object []),
+                               "args",
+                               new CodeArrayCreateExpression (typeof (object), new CodePrimitiveExpression (outArgs.Count)));
+                       cm.Statements.Add (argsDecl);
+
+                       call = new CodeCastExpression (
+                               context.EndMethod.ReturnType,
+                               new CodeMethodInvokeExpression (
+                               new CodeBaseReferenceExpression (),
+                               "EndInvoke",
+                               new CodePrimitiveExpression (od.Name),
+                               new CodeVariableReferenceExpression ("args"),
+                               new CodeArgumentReferenceExpression (resultArgName)));
+
+                       if (cm.ReturnType.BaseType == "System.Void")
+                               cm.Statements.Add (new CodeExpressionStatement (call));
+                       else
+                               cm.Statements.Add (new CodeMethodReturnStatement (call));
+               }
+       }
+}
index 17425629cbe4af24552d291be1b3c17e98140f17..aa7b6bfd1256858ea8dfad8bc0da46dfcb60e526 100644 (file)
@@ -1,3 +1,4 @@
 Driver.cs
 CommandLineOptions.cs
+MoonlightChannelBaseExtension.cs
 
index 8b84f3cc6045d480283b27e57c40009bd2d1c841..d3bfcf3d342548c14229af91f9b7e64bf668915b 100644 (file)
@@ -1,3 +1,56 @@
+2009-08-13  Andrés G. Aragoneses  <aaragoneses@novell.com>
+
+       * Mono.Tuner/MoonlightA11yProcessor.cs: Don't whitelist SC
+         attribs for base methods that are on our assembly.
+       This finally makes a11y work without security disabled. The
+         summary of the troubles encountered:
+       - GetHashCode() -> base method not SC. (r139589+r139649)
+       - Dispose() -> interface method not SC. (r139796)
+       - get_Handle() -> interface method SC while impl not SC. (this
+         commit)
+
+2009-08-12  Andrés G. Aragoneses  <aaragoneses@novell.com>
+
+       * Mono.Tuner/MoonlightA11yProcessor.cs: Look for base methods
+         in interfaces as well.
+
+2009-08-11  Andrés G. Aragoneses  <aaragoneses@novell.com>
+
+       * Mono.Tuner/MoonlightA11yDescriptorGenerator.cs: Yet another
+         blacklisted element (SW.dll is not linked).
+
+2009-08-11  Andrés G. Aragoneses  <aaragoneses@novell.com>
+
+       * Mono.Tuner/MoonlightA11yDescriptorGenerator.cs: Blacklist
+         more stuff.
+
+2009-08-11  Andrés G. Aragoneses  <aaragoneses@novell.com>
+
+       * Mono.Tuner/MoonlightA11yDescriptorGenerator.cs: Blacklist
+         our bridge.
+
+2009-08-10  Andrés G. Aragoneses  <aaragoneses@novell.com>
+
+       * Mono.Tuner/MoonlightA11yProcessor.cs: Move FIXME to a better
+         place. Fix NRE.
+
+2009-08-07  Andrés G. Aragoneses  <aaragoneses@novell.com>
+
+       * Mono.Tuner/MoonlightA11yProcessor.cs: Don't use var.
+       Remove debug spew.
+
+2009-08-07  Andrés G. Aragoneses  <aaragoneses@novell.com>
+
+       * Mono.Tuner/InjectSecurityAttributes.cs: Make an enum
+         and a method protected.
+
+       * Mono.Tuner/MoonlightA11yProcessor.cs: Prevent
+         Type*Exceptions because of badly placed SC attrib on
+         methods.
+
+       * Mono.Tuner/MoonlightA11yDescriptorGenerator.cs: Typo in
+         comment.
+
 2009-07-02  Jb Evain  <jbevain@novell.com>
 
        * Makefile: fix cecil's location.
index 215d450a3412c2cb8a0013a450ecb1df486c4b68..0d4bac44e1e88b4103c2e87bf1592fe7c8b5ad95 100644 (file)
@@ -45,7 +45,7 @@ namespace Mono.Tuner {
                        Method,
                }
 
-               enum AttributeType {
+               protected enum AttributeType {
                        Critical,
                        SafeCritical,
                }
@@ -242,7 +242,7 @@ namespace Mono.Tuner {
                        }
                }
 
-               static bool HasSecurityAttribute (ICustomAttributeProvider provider, AttributeType type)
+               protected static bool HasSecurityAttribute (ICustomAttributeProvider provider, AttributeType type)
                {
                        if (!provider.HasCustomAttributes)
                                return false;
index c0f92a91d4b77371b0a7c58294bb8055bf60031d..bb170d03d402bd380cc87f9e627f248edeedaabc 100644 (file)
@@ -42,6 +42,10 @@ namespace Mono.Tuner {
                XmlTextWriter writer = null;
                protected override void ProcessAssembly (AssemblyDefinition assembly)
                {
+                       if (assembly.Name.Name == "MoonAtkBridge" || assembly.Name.Name == "System.Windows" ||
+                           assembly.Name.Name.Contains ("Dummy"))
+                               return;
+                       
                        if (writer == null) {
                                writer = new XmlTextWriter (System.Console.Out);
                                writer.Formatting = Formatting.Indented;
@@ -112,7 +116,7 @@ namespace Mono.Tuner {
                        return @params;
                }
 
-               Hashtable /*Dictionary<TypeDefinition,List<IAnnotationProvider>>*/ ScanAssembly (AssemblyDefinition assembly)
+               Hashtable /*Dictionary<TypeDefinition,List<IAnnotationProvider>*/ ScanAssembly (AssemblyDefinition assembly)
                {
                        if (Annotations.GetAction (assembly) != AssemblyAction.Link)
                                return null;
index d01a9dc965a98f6870620b2847cfc420ccdb6a78..ad7fe39654813fc50e03c8550dd4b08c1f103f4a 100644 (file)
@@ -87,10 +87,92 @@ namespace Mono.Tuner {
                                                AddCriticalAttribute (ctor);
 
                                if (type.HasMethods)
-                                       foreach (MethodDefinition method in type.Methods)
-                                               AddCriticalAttribute (method);
+                                       foreach (MethodDefinition method in type.Methods) {
+                                               MethodDefinition parent = null;
+                                       
+                                               //TODO: take in account generic params
+                                               if (!method.HasGenericParameters) {
+                                                       
+                                                       /*
+                                                        * we need to scan base methods because the CoreCLR complains about SC attribs added
+                                                        * to overriden methods whose base (virtual or interface) method is not marked as SC
+                                                        * with TypeLoadExceptions
+                                                        */
+                                                       parent = GetBaseMethod (type, method);
+                                               }
+
+                                               //if there's no base method
+                                               if (parent == null ||
+
+                                               //if it's our bridge assembly, we're sure it will (finally, at the end of the linking process) have the SC attrib
+                                                   _assembly.MainModule.Types.Contains (parent.DeclaringType) ||
+
+                                               //if the type is in the moonlight assemblies, check if it has the SC attrib
+                                                   HasSecurityAttribute (parent, AttributeType.Critical))
+
+                                                       AddCriticalAttribute (method);
+                               }
+                               
+                       }
+               }
+               
+               MethodDefinition GetBaseMethod (TypeDefinition finalType, MethodDefinition final)
+               {
+                       // both GetOverridenMethod and GetInterfaceMethod return null if there is no base method
+                       return GetOverridenMethod (finalType, final) ?? GetInterfaceMethod (finalType, final);
+               }
+               
+               //note: will not return abstract methods
+               MethodDefinition GetOverridenMethod (TypeDefinition finalType, MethodDefinition final)
+               {
+                       TypeReference baseType = finalType.BaseType;
+                       while (baseType != null && baseType.Resolve () != null) {
+                               foreach (MethodDefinition method in baseType.Resolve ().Methods) {
+                                       if (!method.IsVirtual || method.Name != final.Name)
+                                               continue;
+                                       
+                                       //TODO: should we discard them?
+                                       if (method.IsAbstract)
+                                               continue;
+                                       
+                                       if (HasSameSignature (method, final))
+                                               return method;
+                               }
+                               baseType = baseType.Resolve().BaseType;
                        }
+                       return null;
                }
+               
+               MethodDefinition GetInterfaceMethod (TypeDefinition finalType, MethodDefinition final)
+               {
+                       TypeDefinition baseType = finalType;
+                       while (baseType != null) {
+                               if (baseType.HasInterfaces)
+                                       foreach (TypeReference @interface in baseType.Interfaces)
+                                               foreach (MethodDefinition method in @interface.Resolve ().Methods)
+                                                       if (method.Name == final.Name && HasSameSignature (method, final))
+                                                               return method;
+
+                               baseType = baseType.BaseType == null ? null : baseType.BaseType.Resolve ();
+                       }
+                       return null;
+               }
+               
+               bool HasSameSignature (MethodDefinition method1, MethodDefinition method2)
+               {
+                       if (method1.ReturnType.ReturnType.FullName != method2.ReturnType.ReturnType.FullName)
+                               return false;
+                       
+                       if (method1.Parameters.Count != method2.Parameters.Count)
+                               return false;
 
+                       for (int i = 0; i < method1.Parameters.Count; i++) {
+                               if (method1.Parameters [i].ParameterType.FullName !=
+                                   method2.Parameters [i].ParameterType.FullName)
+                                       return false;
+                       }
+                       
+                       return true;
+               }
        }
 }
index 7afcf1a916e18444826b58673ffe63c058d1acf4..b6157c51cfbfdf373d7de059b88756e05d0af017 100644 (file)
@@ -1,3 +1,51 @@
+2009-08-19  Ankit Jain  <jankit@novell.com>
+
+       * xbuild/Microsoft.Common.targets (ResolveAssemblyReference):
+       Make SearchPaths get value from a property (AssemblySearchPaths)
+       to allow it to be overridden.
+
+2009-08-18  Ankit Jain  <jankit@novell.com>
+
+       * SolutionParser.cs (ParseSolution): Project reference in a project
+       file, but not found in .sln file is ignored. Also, add dependencies
+       specified in the .sln file.
+
+2009-08-14  Ankit Jain  <jankit@novell.com>
+
+       Fix bug #530368.
+       * SolutionParser.cs (AddProjectTargets): If a project name matches one
+       of the targets that we emit (Build/Clean etc), then rename to
+       "Solution:<project name>".
+
+2009-08-14  Ankit Jain  <jankit@novell.com>
+
+       * xbuild/Microsoft.Common.targets (AllowUnsafeBlocks): Don't set any
+       default value.
+       (OutputPath): Set a default value.
+       (DeployOutputFiles): Copy only if something available to copy.
+
+2009-08-14  Ankit Jain  <jankit@novell.com>
+
+       * SolutionParser.cs (ProjectInfo.Dependencies): Change to a dictionary
+       to keep track of corresponding ProjectInfo objects.
+       (ParseSolution): Refactor to populate the ProjectInfo.Dependencies
+       dictionary. Use AddBuildLevels to emit build levels to allow
+       parallel builds.
+       (AddProjectTargets): Dependency's projectInfo is directly available now.
+       (AddBuildLevels): New. Emit items named BuildLevelN, where each level
+       has projects that can be built in parallel. Lower levels represent
+       dependencies for higher levels.
+       (AddSolutionTargets): Instead of using CallTarget, directly use MSBuild
+       task with the new BuildLevelN stuff. Also tell the user about disabled
+       projects or missing project configs.
+       (TopologicalSort): New.
+       (Insert): New. Based on code from monodevelop.
+
+2009-08-14  Ankit Jain  <jankit@novell.com>
+
+       * xbuild/Microsoft.Common.targets (ResolveAssemblyReference): Add
+       '{PkgConfig}' to SearchPaths.
+
 2009-07-31  Ankit Jain  <jankit@novell.com>
 
        * ErrorUtilities.cs (ShowUsage): Implement.
index d924f80f7921a0374c03cf87acb7271cdc0815f7..78c078bce41c5d905d4510a8cc56ea340a588053 100644 (file)
@@ -35,7 +35,7 @@ namespace Mono.XBuild.CommandLine {
                static string[] version = {
                        String.Format ("XBuild Engine Version {0}", Consts.MonoVersion),
                        String.Format ("Mono, Version {0}", Consts.MonoVersion),
-                       "Copyright (C) Marek Sieradzki 2005. All rights reserved.",
+                       "Copyright (C) Marek Sieradzki 2005-2008, Novell 2008-2009.",
                };
 
                
index 5d7e6c48b89ca41934852f04c13205010a661024..6289e0e00a250d3f55d2491c1d6acfa39c65bcf4 100644 (file)
@@ -3,8 +3,11 @@
 //
 // Author:
 //   Jonathan Chambers (joncham@gmail.com)
+//   Ankit Jain <jankit@novell.com>
+//   Lluis Sanchez Gual <lluis@novell.com>
 //
 // (C) 2009 Jonathan Chambers
+// Copyright 2008, 2009 Novell, Inc (http://www.novell.com)
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -46,7 +49,7 @@ namespace Mono.XBuild.CommandLine {
                }
 
                public Dictionary<TargetInfo, TargetInfo> TargetMap = new Dictionary<TargetInfo, TargetInfo> ();
-               public List<Guid> Dependencies = new List<Guid> ();
+               public Dictionary<Guid, ProjectInfo> Dependencies = new Dictionary<Guid, ProjectInfo> ();
        }
 
        struct TargetInfo {
@@ -118,20 +121,13 @@ namespace Mono.XBuild.CommandLine {
 
                                projectInfos.Add (new Guid (m.Groups[4].Value), projectInfo);
 
-                               Project currentProject = p.ParentEngine.CreateNewProject ();
-                               currentProject.Load (Path.Combine (solutionDir,
-                                                       projectInfo.FileName.Replace ('\\', Path.DirectorySeparatorChar)));
-
-                               foreach (BuildItem bi in currentProject.GetEvaluatedItemsByName ("ProjectReference")) {
-                                       string projectReferenceGuid = bi.GetEvaluatedMetadata ("Project");
-                                       projectInfo.Dependencies.Add (new Guid (projectReferenceGuid));
-                               }
-
                                Match projectSectionMatch = projectDependenciesRegex.Match (m.Groups[6].Value);
                                while (projectSectionMatch.Success) {
                                        Match projectDependencyMatch = projectDependencyRegex.Match (projectSectionMatch.Value);
                                        while (projectDependencyMatch.Success) {
-                                               projectInfo.Dependencies.Add (new Guid (projectDependencyMatch.Groups[1].Value));
+                                               // we might not have projectInfo available right now, so
+                                               // set it to null, and fill it in later
+                                               projectInfo.Dependencies [new Guid (projectDependencyMatch.Groups[1].Value)] = null;
                                                projectDependencyMatch = projectDependencyMatch.NextMatch ();
                                        }
                                        projectSectionMatch = projectSectionMatch.NextMatch ();
@@ -139,6 +135,38 @@ namespace Mono.XBuild.CommandLine {
                                m = m.NextMatch ();
                        }
 
+                       foreach (ProjectInfo projectInfo in projectInfos.Values) {
+                               Project currentProject = p.ParentEngine.CreateNewProject ();
+                               currentProject.Load (Path.Combine (solutionDir,
+                                                       projectInfo.FileName.Replace ('\\', Path.DirectorySeparatorChar)));
+
+                               foreach (BuildItem bi in currentProject.GetEvaluatedItemsByName ("ProjectReference")) {
+                                       string projectReferenceGuid = bi.GetEvaluatedMetadata ("Project");
+                                       Guid guid = new Guid (projectReferenceGuid);
+                                       ProjectInfo info = projectInfos [guid];
+                                       if (info != null)
+                                               // ignore if not found
+                                               projectInfo.Dependencies [guid] = info;
+                               }
+                       }
+
+                       // fill in the project info for deps found in the .sln file
+                       foreach (ProjectInfo projectInfo in projectInfos.Values) {
+                               List<Guid> missingInfos = new List<Guid> ();
+                               foreach (KeyValuePair<Guid, ProjectInfo> dependency in projectInfo.Dependencies) {
+                                       if (dependency.Value == null)
+                                               missingInfos.Add (dependency.Key);
+                               }
+
+                               foreach (Guid guid in missingInfos) {
+                                       ProjectInfo info;
+                                       if (projectInfos.TryGetValue (guid, out info))
+                                               projectInfo.Dependencies [guid] = info;
+                                       else
+                                               projectInfo.Dependencies.Remove (guid);
+                               }
+                       }
+
                        Match globalMatch = globalRegex.Match (line);
                        Match globalSectionMatch = globalSectionRegex.Match (globalMatch.Groups[1].Value);
                        while (globalSectionMatch.Success) {
@@ -162,11 +190,12 @@ namespace Mono.XBuild.CommandLine {
                                globalSectionMatch = globalSectionMatch.NextMatch ();
                        }
 
+                       int num_levels = AddBuildLevels (p, solutionTargets, projectInfos);
+
                        AddCurrentSolutionConfigurationContents (p, solutionTargets, projectInfos);
                        AddValidateSolutionConfiguration (p);
                        AddProjectTargets (p, solutionTargets, projectInfos);
-                       AddSolutionTargets (p, projectInfos);
-
+                       AddSolutionTargets (p, num_levels);
                }
 
                void AddGeneralSettings (string solutionFile, Project p)
@@ -325,21 +354,28 @@ namespace Mono.XBuild.CommandLine {
                        foreach (KeyValuePair<Guid, ProjectInfo> projectInfo in projectInfos) {
                                ProjectInfo project = projectInfo.Value;
                                foreach (string buildTarget in buildTargets) {
-                                       Target target = p.Targets.AddNewTarget (project.Name + (buildTarget == "Build" ? string.Empty : ":" + buildTarget));
+                                       string target_name = project.Name +
+                                               (buildTarget == "Build" ? string.Empty : ":" + buildTarget);
+
+                                       if (IsBuildTargetName (project.Name))
+                                               target_name = "Solution:" + target_name;
+
+                                       Target target = p.Targets.AddNewTarget (target_name);
                                        target.Condition = "'$(CurrentSolutionConfigurationContents)' != ''"; 
-                                       string dependencies = string.Empty;
-                                       foreach (Guid dependency in project.Dependencies) {
-                                               ProjectInfo dependentInfo;
-                                               if (projectInfos.TryGetValue (dependency, out dependentInfo)) {
+
+                                       if (project.Dependencies.Count > 0) {
+                                               StringBuilder dependencies = new StringBuilder ();
+                                               foreach (ProjectInfo dependentInfo in project.Dependencies.Values) {
                                                        if (dependencies.Length > 0)
-                                                               dependencies += ";";
-                                                       dependencies += dependentInfo.Name;
+                                                               dependencies.Append (";");
+                                                       if (IsBuildTargetName (dependentInfo.Name))
+                                                               dependencies.Append ("Solution:");
+                                                       dependencies.Append (dependentInfo.Name);
                                                        if (buildTarget != "Build")
-                                                               dependencies += ":" + buildTarget;
+                                                               dependencies.Append (":" + buildTarget);
                                                }
+                                               target.DependsOnTargets = dependencies.ToString ();
                                        }
-                                       if (dependencies != string.Empty)
-                                               target.DependsOnTargets = dependencies;
 
                                        foreach (TargetInfo targetInfo in solutionTargets) {
                                                BuildTask task = null;
@@ -352,7 +388,7 @@ namespace Mono.XBuild.CommandLine {
                                                if (projectTargetInfo.Build) {
                                                        task = target.AddNewTask ("MSBuild");
                                                        task.SetParameterValue ("Projects", project.FileName);
-                                                       
+
                                                        if (buildTarget != "Build")
                                                                task.SetParameterValue ("Targets", buildTarget);
                                                        task.SetParameterValue ("Properties", string.Format ("Configuration={0}; Platform={1}; BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)", projectTargetInfo.Configuration, projectTargetInfo.Platform));
@@ -366,24 +402,155 @@ namespace Mono.XBuild.CommandLine {
                        }
                }
 
-               void AddSolutionTargets (Project p, Dictionary<Guid, ProjectInfo> projectInfos)
+               bool IsBuildTargetName (string name)
+               {
+                       foreach (string tgt in buildTargets)
+                               if (name == tgt)
+                                       return true;
+                       return false;
+               }
+
+               // returns number of levels
+               int AddBuildLevels (Project p, List<TargetInfo> solutionTargets, Dictionary<Guid, ProjectInfo> projectInfos)
+               {
+                       List<ProjectInfo>[] infosByLevel = TopologicalSort<ProjectInfo> (projectInfos.Values);
+
+                       foreach (TargetInfo targetInfo in solutionTargets) {
+                               BuildItemGroup big = p.AddNewItemGroup ();
+                               big.Condition = String.Format (" ('$(Configuration)' == '{0}') and ('$(Platform)' == '{1}') ",
+                                               targetInfo.Configuration, targetInfo.Platform);
+
+                               //FIXME: every level has projects that can be built in parallel.
+                               //       levels are ordered on the basis of the dependency graph
+
+                               for (int i = 0; i < infosByLevel.Length; i ++) {
+                                       string build_level = String.Format ("BuildLevel{0}", i);
+                                       string skip_level = String.Format ("SkipLevel{0}", i);
+                                       string missing_level = String.Format ("MissingConfigLevel{0}", i);
+
+                                       foreach (ProjectInfo projectInfo in infosByLevel [i]) {
+                                               TargetInfo projectTargetInfo;
+                                               if (!projectInfo.TargetMap.TryGetValue (targetInfo, out projectTargetInfo)) {
+                                                       // missing project config
+                                                       big.AddNewItem (missing_level, projectInfo.Name);
+                                                       continue;
+                                               }
+
+                                               if (projectTargetInfo.Build) {
+                                                       BuildItem item = big.AddNewItem (build_level, projectInfo.FileName);
+                                                       item.SetMetadata ("Configuration", projectTargetInfo.Configuration);
+                                                       item.SetMetadata ("Platform", projectTargetInfo.Platform);
+                                               } else {
+                                                       // build disabled
+                                                       big.AddNewItem (skip_level, projectInfo.Name);
+                                               }
+                                       }
+                               }
+                       }
+
+                       return infosByLevel.Length;
+               }
+
+               void AddSolutionTargets (Project p, int num_levels)
                {
                        foreach (string buildTarget in buildTargets) {
                                Target t = p.Targets.AddNewTarget (buildTarget);
                                t.Condition = "'$(CurrentSolutionConfigurationContents)' != ''";
-                               BuildTask task = t.AddNewTask ("CallTarget");
-                               string targets = string.Empty;
-                               foreach (KeyValuePair<Guid, ProjectInfo> projectInfo in projectInfos) {
-                                       if (targets.Length > 0)
-                                               targets += ";";
-                                       targets += projectInfo.Value.Name;
+
+                               for (int i = 0; i < num_levels; i ++) {
+                                       string level_str = String.Format ("BuildLevel{0}", i);
+                                       BuildTask task = t.AddNewTask ("MSBuild");
+                                       task.SetParameterValue ("Condition", String.Format ("'@({0})' != ''", level_str));
+                                       task.SetParameterValue ("Projects", String.Format ("@({0})", level_str));
+                                       task.SetParameterValue ("Properties",
+                                               string.Format ("Configuration=%(Configuration); Platform=%(Platform); BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)"));
                                        if (buildTarget != "Build")
-                                               targets += ":" + buildTarget;
+                                               task.SetParameterValue ("Targets", buildTarget);
+                                       //FIXME: change this to BuildInParallel=true, when parallel
+                                       //       build support gets added
+                                       task.SetParameterValue ("RunEachTargetSeparately", "true");
+
+                                       level_str = String.Format ("SkipLevel{0}", i);
+                                       task = t.AddNewTask ("Message");
+                                       task.Condition = String.Format ("'@({0})' != ''", level_str);
+                                       task.SetParameterValue ("Text",
+                                               String.Format ("The project '%({0}.Identity)' is disabled for solution " +
+                                                       "configuration '$(Configuration)|$(Platform)'.", level_str));
+
+                                       level_str = String.Format ("MissingConfigLevel{0}", i);
+                                       task = t.AddNewTask ("Warning");
+                                       task.Condition = String.Format ("'@({0})' != ''", level_str);
+                                       task.SetParameterValue ("Text",
+                                               String.Format ("The project configuration for project '%({0}.Identity)' " +
+                                                       "corresponding to the solution configuration " +
+                                                       "'$(Configuration)|$(Platform)' was not found.", level_str));
                                }
-                               task.SetParameterValue ("Targets", targets);
-                               task.SetParameterValue ("RunEachTargetSeparately", "true");
                        }
                }
+
+               // Sorts the ProjectInfo dependency graph, to obtain
+               // a series of build levels with projects. Projects
+               // in each level can be run parallel (no inter-dependency).
+               static List<T>[] TopologicalSort<T> (IEnumerable<T> items) where T: ProjectInfo
+               {
+                       IList<T> allItems;
+                       allItems = items as IList<T>;
+                       if (allItems == null)
+                               allItems = new List<T> (items);
+
+                       bool[] inserted = new bool[allItems.Count];
+                       bool[] triedToInsert = new bool[allItems.Count];
+                       int[] levels = new int [allItems.Count];
+
+                       int maxdepth = 0;
+                       for (int i = 0; i < allItems.Count; ++i) {
+                               int d = Insert<T> (i, allItems, levels, inserted, triedToInsert);
+                               if (d > maxdepth)
+                                       maxdepth = d;
+                       }
+
+                       // Separate out the project infos by build level
+                       List<T>[] infosByLevel = new List<T>[maxdepth];
+                       for (int i = 0; i < levels.Length; i ++) {
+                               int level = levels [i] - 1;
+                               if (infosByLevel [level] == null)
+                                       infosByLevel [level] = new List<T> ();
+
+                               infosByLevel [level].Add (allItems [i]);
+                       }
+
+                       return infosByLevel;
+               }
+
+               // returns level# for the project
+               static int Insert<T> (int index, IList<T> allItems, int[] levels, bool[] inserted, bool[] triedToInsert)
+                       where T: ProjectInfo
+               {
+                       if (inserted [index])
+                               return levels [index];
+
+                       if (triedToInsert[index])
+                               throw new InvalidOperationException ("Cyclic dependency found in the project dependency graph");
+
+                       triedToInsert[index] = true;
+                       ProjectInfo insertItem = allItems[index];
+
+                       int maxdepth = 0;
+                       foreach (ProjectInfo dependency in insertItem.Dependencies.Values) {
+                               for (int j = 0; j < allItems.Count; ++j) {
+                                       ProjectInfo checkItem = allItems [j];
+                                       if (dependency.FileName == checkItem.FileName) {
+                                               int d = Insert (j, allItems, levels, inserted, triedToInsert);
+                                               maxdepth = d > maxdepth ? d : maxdepth;
+                                               break;
+                                       }
+                               }
+                       }
+                       levels [index] = maxdepth + 1;
+                       inserted [index] = true;
+
+                       return levels [index];
+               }
        }
 }
 
index dadb72776d690a2c7cb0afe277fe09960462b70f..8834fd145065f8b920a999c1a404994134b9ee1a 100644 (file)
@@ -1,3 +1,7 @@
+2009-08-14  Ankit Jain  <jankit@novell.com>
+
+       * standalone/Project01: Update .sln.proj file.
+
 2009-07-30  Ankit Jain  <jankit@novell.com>
 
        * standalone/Project01/final-outputs.txt: Update to include obj/
index 0fd248b5b478f7840eda211f23d6d42e3706bef3..6775735d5038b9ebc5202730287742c282217505 100644 (file)
     <SolutionName>Project01</SolutionName>
     <SolutionPath>/home/radical/w1/mcs/tools/xbuild/tests/standalone/Project01/Project01.sln</SolutionPath>
   </PropertyGroup>
+  <ItemGroup Condition=" ('$(Configuration)' == 'Debug') and ('$(Platform)' == 'Any CPU') ">
+    <BuildLevel0 Include="Lib3\Lib3.csproj">
+      <Configuration>Release</Configuration>
+      <Platform>AnyCPU</Platform>
+    </BuildLevel0>
+    <BuildLevel0 Include="Lib4\Lib4.csproj">
+      <Configuration>Debug</Configuration>
+      <Platform>AnyCPU</Platform>
+    </BuildLevel0>
+    <BuildLevel1 Include="Lib2\Lib2.csproj">
+      <Configuration>Debug</Configuration>
+      <Platform>AnyCPU</Platform>
+    </BuildLevel1>
+    <BuildLevel2 Include="Lib1\Lib1.csproj">
+      <Configuration>Release</Configuration>
+      <Platform>AnyCPU</Platform>
+    </BuildLevel2>
+    <BuildLevel3 Include="Project01\Main.csproj">
+      <Configuration>Debug</Configuration>
+      <Platform>AnyCPU</Platform>
+    </BuildLevel3>
+  </ItemGroup>
+  <ItemGroup Condition=" ('$(Configuration)' == 'Release') and ('$(Platform)' == 'Any CPU') ">
+    <BuildLevel0 Include="Lib3\Lib3.csproj">
+      <Configuration>Release</Configuration>
+      <Platform>AnyCPU</Platform>
+    </BuildLevel0>
+    <BuildLevel0 Include="Lib4\Lib4.csproj">
+      <Configuration>Release</Configuration>
+      <Platform>AnyCPU</Platform>
+    </BuildLevel0>
+    <BuildLevel1 Include="Lib2\Lib2.csproj">
+      <Configuration>Release</Configuration>
+      <Platform>AnyCPU</Platform>
+    </BuildLevel1>
+    <BuildLevel2 Include="Lib1\Lib1.csproj">
+      <Configuration>Release</Configuration>
+      <Platform>AnyCPU</Platform>
+    </BuildLevel2>
+    <BuildLevel3 Include="Project01\Main.csproj">
+      <Configuration>Release</Configuration>
+      <Platform>AnyCPU</Platform>
+    </BuildLevel3>
+  </ItemGroup>
   <PropertyGroup Condition=" '$(Configuration)' == '' ">
     <Configuration>Debug</Configuration>
   </PropertyGroup>
     <MSBuild Projects="Lib4\Lib4.csproj" Targets="Publish" Properties="Configuration=Release; Platform=AnyCPU; BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" Condition=" ('$(Configuration)' == 'Release') and ('$(Platform)' == 'Any CPU') " />
   </Target>
   <Target Name="Build" Condition="'$(CurrentSolutionConfigurationContents)' != ''">
-    <CallTarget Targets="Main;Lib1;Lib2;Lib3;Lib4" RunEachTargetSeparately="true" />
+    <MSBuild Condition="'@(BuildLevel0)' != ''" Projects="@(BuildLevel0)" Properties="Configuration=%(Configuration); Platform=%(Platform); BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" RunEachTargetSeparately="true" />
+    <Message Condition="'@(SkipLevel0)' != ''" Text="The project '%(SkipLevel0.Identity)' is disabled for solution configuration '$(Configuration)|$(Platform)'." />
+    <Warning Condition="'@(MissingConfigLevel0)' != ''" Text="The project configuration for project '%(MissingConfigLevel0.Identity)' corresponding to the solution configuration '$(Configuration)|$(Platform)' was not found." />
+    <MSBuild Condition="'@(BuildLevel1)' != ''" Projects="@(BuildLevel1)" Properties="Configuration=%(Configuration); Platform=%(Platform); BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" RunEachTargetSeparately="true" />
+    <Message Condition="'@(SkipLevel1)' != ''" Text="The project '%(SkipLevel1.Identity)' is disabled for solution configuration '$(Configuration)|$(Platform)'." />
+    <Warning Condition="'@(MissingConfigLevel1)' != ''" Text="The project configuration for project '%(MissingConfigLevel1.Identity)' corresponding to the solution configuration '$(Configuration)|$(Platform)' was not found." />
+    <MSBuild Condition="'@(BuildLevel2)' != ''" Projects="@(BuildLevel2)" Properties="Configuration=%(Configuration); Platform=%(Platform); BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" RunEachTargetSeparately="true" />
+    <Message Condition="'@(SkipLevel2)' != ''" Text="The project '%(SkipLevel2.Identity)' is disabled for solution configuration '$(Configuration)|$(Platform)'." />
+    <Warning Condition="'@(MissingConfigLevel2)' != ''" Text="The project configuration for project '%(MissingConfigLevel2.Identity)' corresponding to the solution configuration '$(Configuration)|$(Platform)' was not found." />
+    <MSBuild Condition="'@(BuildLevel3)' != ''" Projects="@(BuildLevel3)" Properties="Configuration=%(Configuration); Platform=%(Platform); BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" RunEachTargetSeparately="true" />
+    <Message Condition="'@(SkipLevel3)' != ''" Text="The project '%(SkipLevel3.Identity)' is disabled for solution configuration '$(Configuration)|$(Platform)'." />
+    <Warning Condition="'@(MissingConfigLevel3)' != ''" Text="The project configuration for project '%(MissingConfigLevel3.Identity)' corresponding to the solution configuration '$(Configuration)|$(Platform)' was not found." />
   </Target>
   <Target Name="Clean" Condition="'$(CurrentSolutionConfigurationContents)' != ''">
-    <CallTarget Targets="Main:Clean;Lib1:Clean;Lib2:Clean;Lib3:Clean;Lib4:Clean" RunEachTargetSeparately="true" />
+    <MSBuild Condition="'@(BuildLevel0)' != ''" Projects="@(BuildLevel0)" Properties="Configuration=%(Configuration); Platform=%(Platform); BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" Targets="Clean" RunEachTargetSeparately="true" />
+    <Message Condition="'@(SkipLevel0)' != ''" Text="The project '%(SkipLevel0.Identity)' is disabled for solution configuration '$(Configuration)|$(Platform)'." />
+    <Warning Condition="'@(MissingConfigLevel0)' != ''" Text="The project configuration for project '%(MissingConfigLevel0.Identity)' corresponding to the solution configuration '$(Configuration)|$(Platform)' was not found." />
+    <MSBuild Condition="'@(BuildLevel1)' != ''" Projects="@(BuildLevel1)" Properties="Configuration=%(Configuration); Platform=%(Platform); BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" Targets="Clean" RunEachTargetSeparately="true" />
+    <Message Condition="'@(SkipLevel1)' != ''" Text="The project '%(SkipLevel1.Identity)' is disabled for solution configuration '$(Configuration)|$(Platform)'." />
+    <Warning Condition="'@(MissingConfigLevel1)' != ''" Text="The project configuration for project '%(MissingConfigLevel1.Identity)' corresponding to the solution configuration '$(Configuration)|$(Platform)' was not found." />
+    <MSBuild Condition="'@(BuildLevel2)' != ''" Projects="@(BuildLevel2)" Properties="Configuration=%(Configuration); Platform=%(Platform); BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" Targets="Clean" RunEachTargetSeparately="true" />
+    <Message Condition="'@(SkipLevel2)' != ''" Text="The project '%(SkipLevel2.Identity)' is disabled for solution configuration '$(Configuration)|$(Platform)'." />
+    <Warning Condition="'@(MissingConfigLevel2)' != ''" Text="The project configuration for project '%(MissingConfigLevel2.Identity)' corresponding to the solution configuration '$(Configuration)|$(Platform)' was not found." />
+    <MSBuild Condition="'@(BuildLevel3)' != ''" Projects="@(BuildLevel3)" Properties="Configuration=%(Configuration); Platform=%(Platform); BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" Targets="Clean" RunEachTargetSeparately="true" />
+    <Message Condition="'@(SkipLevel3)' != ''" Text="The project '%(SkipLevel3.Identity)' is disabled for solution configuration '$(Configuration)|$(Platform)'." />
+    <Warning Condition="'@(MissingConfigLevel3)' != ''" Text="The project configuration for project '%(MissingConfigLevel3.Identity)' corresponding to the solution configuration '$(Configuration)|$(Platform)' was not found." />
   </Target>
   <Target Name="Rebuild" Condition="'$(CurrentSolutionConfigurationContents)' != ''">
-    <CallTarget Targets="Main:Rebuild;Lib1:Rebuild;Lib2:Rebuild;Lib3:Rebuild;Lib4:Rebuild" RunEachTargetSeparately="true" />
+    <MSBuild Condition="'@(BuildLevel0)' != ''" Projects="@(BuildLevel0)" Properties="Configuration=%(Configuration); Platform=%(Platform); BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" Targets="Rebuild" RunEachTargetSeparately="true" />
+    <Message Condition="'@(SkipLevel0)' != ''" Text="The project '%(SkipLevel0.Identity)' is disabled for solution configuration '$(Configuration)|$(Platform)'." />
+    <Warning Condition="'@(MissingConfigLevel0)' != ''" Text="The project configuration for project '%(MissingConfigLevel0.Identity)' corresponding to the solution configuration '$(Configuration)|$(Platform)' was not found." />
+    <MSBuild Condition="'@(BuildLevel1)' != ''" Projects="@(BuildLevel1)" Properties="Configuration=%(Configuration); Platform=%(Platform); BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" Targets="Rebuild" RunEachTargetSeparately="true" />
+    <Message Condition="'@(SkipLevel1)' != ''" Text="The project '%(SkipLevel1.Identity)' is disabled for solution configuration '$(Configuration)|$(Platform)'." />
+    <Warning Condition="'@(MissingConfigLevel1)' != ''" Text="The project configuration for project '%(MissingConfigLevel1.Identity)' corresponding to the solution configuration '$(Configuration)|$(Platform)' was not found." />
+    <MSBuild Condition="'@(BuildLevel2)' != ''" Projects="@(BuildLevel2)" Properties="Configuration=%(Configuration); Platform=%(Platform); BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" Targets="Rebuild" RunEachTargetSeparately="true" />
+    <Message Condition="'@(SkipLevel2)' != ''" Text="The project '%(SkipLevel2.Identity)' is disabled for solution configuration '$(Configuration)|$(Platform)'." />
+    <Warning Condition="'@(MissingConfigLevel2)' != ''" Text="The project configuration for project '%(MissingConfigLevel2.Identity)' corresponding to the solution configuration '$(Configuration)|$(Platform)' was not found." />
+    <MSBuild Condition="'@(BuildLevel3)' != ''" Projects="@(BuildLevel3)" Properties="Configuration=%(Configuration); Platform=%(Platform); BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" Targets="Rebuild" RunEachTargetSeparately="true" />
+    <Message Condition="'@(SkipLevel3)' != ''" Text="The project '%(SkipLevel3.Identity)' is disabled for solution configuration '$(Configuration)|$(Platform)'." />
+    <Warning Condition="'@(MissingConfigLevel3)' != ''" Text="The project configuration for project '%(MissingConfigLevel3.Identity)' corresponding to the solution configuration '$(Configuration)|$(Platform)' was not found." />
   </Target>
   <Target Name="Publish" Condition="'$(CurrentSolutionConfigurationContents)' != ''">
-    <CallTarget Targets="Main:Publish;Lib1:Publish;Lib2:Publish;Lib3:Publish;Lib4:Publish" RunEachTargetSeparately="true" />
+    <MSBuild Condition="'@(BuildLevel0)' != ''" Projects="@(BuildLevel0)" Properties="Configuration=%(Configuration); Platform=%(Platform); BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" Targets="Publish" RunEachTargetSeparately="true" />
+    <Message Condition="'@(SkipLevel0)' != ''" Text="The project '%(SkipLevel0.Identity)' is disabled for solution configuration '$(Configuration)|$(Platform)'." />
+    <Warning Condition="'@(MissingConfigLevel0)' != ''" Text="The project configuration for project '%(MissingConfigLevel0.Identity)' corresponding to the solution configuration '$(Configuration)|$(Platform)' was not found." />
+    <MSBuild Condition="'@(BuildLevel1)' != ''" Projects="@(BuildLevel1)" Properties="Configuration=%(Configuration); Platform=%(Platform); BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" Targets="Publish" RunEachTargetSeparately="true" />
+    <Message Condition="'@(SkipLevel1)' != ''" Text="The project '%(SkipLevel1.Identity)' is disabled for solution configuration '$(Configuration)|$(Platform)'." />
+    <Warning Condition="'@(MissingConfigLevel1)' != ''" Text="The project configuration for project '%(MissingConfigLevel1.Identity)' corresponding to the solution configuration '$(Configuration)|$(Platform)' was not found." />
+    <MSBuild Condition="'@(BuildLevel2)' != ''" Projects="@(BuildLevel2)" Properties="Configuration=%(Configuration); Platform=%(Platform); BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" Targets="Publish" RunEachTargetSeparately="true" />
+    <Message Condition="'@(SkipLevel2)' != ''" Text="The project '%(SkipLevel2.Identity)' is disabled for solution configuration '$(Configuration)|$(Platform)'." />
+    <Warning Condition="'@(MissingConfigLevel2)' != ''" Text="The project configuration for project '%(MissingConfigLevel2.Identity)' corresponding to the solution configuration '$(Configuration)|$(Platform)' was not found." />
+    <MSBuild Condition="'@(BuildLevel3)' != ''" Projects="@(BuildLevel3)" Properties="Configuration=%(Configuration); Platform=%(Platform); BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" Targets="Publish" RunEachTargetSeparately="true" />
+    <Message Condition="'@(SkipLevel3)' != ''" Text="The project '%(SkipLevel3.Identity)' is disabled for solution configuration '$(Configuration)|$(Platform)'." />
+    <Warning Condition="'@(MissingConfigLevel3)' != ''" Text="The project configuration for project '%(MissingConfigLevel3.Identity)' corresponding to the solution configuration '$(Configuration)|$(Platform)' was not found." />
   </Target>
 </Project>
\ No newline at end of file
index f0a4a20669e398bab3860b40f16a8a4248c9cdda..cb45a3f091183d76c38cfafafdea85aa3440bf0c 100644 (file)
@@ -12,9 +12,9 @@
        </PropertyGroup>
 
        <PropertyGroup>
-               <AllowUnsafeBlocks Condition="'$(AllowUnsafeBlocks)' == ''">false</AllowUnsafeBlocks>
                <AssemblyName Condition="'$(AssemblyName)' == ''">$(RootNamespace)</AssemblyName>
                <OutputPath Condition="'$(OutputPath)' != '' and !HasTrailingSlash('$(OutputPath)')">$(OutputPath)\</OutputPath> 
+               <OutputPath Condition=" '$(Platform)'=='' and '$(Configuration)'=='' and '$(OutputPath)'=='' ">bin\Debug\</OutputPath>
                <WarningLevel Condition="'$(WarningLevel)' == ''" >2</WarningLevel>
        </PropertyGroup>
 
                <AllowedReferenceRelatedFileExtensions Condition=" '$(AllowedReferenceRelatedFileExtensions)' == '' ">
                        .mdb
                </AllowedReferenceRelatedFileExtensions>
+
+               <AssemblySearchPaths Condition="'$(AssemblySearchPaths)' == ''">
+                       {CandidateAssemblyFiles};
+                       {HintPathFromItem};
+                       {TargetFrameworkDirectory};
+                       {PkgConfig};
+                       {GAC};
+                       {RawFileName};
+                       $(OutDir)
+               </AssemblySearchPaths>
        </PropertyGroup>
 
        <Target Name="ResolveAssemblyReferences">
                <ResolveAssemblyReference
                        Assemblies="@(Reference)"
                        AssemblyFiles="@(ChildProjectReferences)"
-                       SearchPaths="{CandidateAssemblyFiles};{HintPathFromItem};{TargetFrameworkDirectory};{GAC};{RawFileName};$(OutDir)"
+                       SearchPaths="$(AssemblySearchPaths)"
                        CandidateAssemblyFiles="@(Content);@(None)"
                        TargetFrameworkDirectories="$(TargetFrameworkPath)"
                        AllowedAssemblyExtensions="$(AllowedReferenceAssemblyFileExtensions)"
                <Copy
                        SourceFiles = "@(IntermediateSatelliteAssemblies)"
                        DestinationFiles = "@(IntermediateSatelliteAssemblies->'$(OutDir)\%(Culture)\$(AssemblyName).resources.dll')"
+                       Condition = "'@(IntermediateSatelliteAssemblies)' != ''"
                        SkipUnchangedFiles="true">
                        <Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
                </Copy>
                <Copy SourceFiles="@(ItemsToCopyToOutputDirectoryAlways)"
                        DestinationFiles="@(ItemsToCopyToOutputDirectoryAlways->'$(OutDir)%(TargetPath)')">
                        <Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
-                       <Output TaskParameter="DestinationFiles" ItemName="FileWrites2"/>
                </Copy>
        </Target>
 
index 00ad6902629ecc75225a6426795680724eaa9a2e..cc9f0ecd74a35183be5feae0f094349724157b24 100644 (file)
@@ -1,3 +1,7 @@
+2009-08-14  Zoltan Varga  <vargaz@gmail.com>
+
+       * arm/arm-codegen.h: Add armv6 MOVW/MOVT.
+
 2009-07-03  Jerry Maine  <crashfourit@gmail.com>
        
        Contributed under the terms of the MIT/X11 license by
index 58088904a01c02abd217b172900de6dff2a5a64e..1503318ba19b175db7be34b12c777d4a990c94fb 100644 (file)
@@ -1076,6 +1076,13 @@ typedef union {
        arminstr_t      raw;
 } ARMInstr;
 
+/* ARMv6t2 */
+
+#define ARM_MOVW_REG_IMM_COND(p, rd, imm16, cond) ARM_EMIT(p, (((cond) << 28) | (3 << 24) | (0 << 20) | ((((guint32)(imm16)) >> 12) << 16) | ((rd) << 12) | (((guint32)(imm16)) & 0xfff)))
+#define ARM_MOVW_REG_IMM(p, rd, imm16) ARM_MOVW_REG_IMM_COND ((p), (rd), (imm16), ARMCOND_AL)
+
+#define ARM_MOVT_REG_IMM_COND(p, rd, imm16, cond) ARM_EMIT(p, (((cond) << 28) | (3 << 24) | (4 << 20) | ((((guint32)(imm16)) >> 12) << 16) | ((rd) << 12) | (((guint32)(imm16)) & 0xfff)))
+#define ARM_MOVT_REG_IMM(p, rd, imm16) ARM_MOVT_REG_IMM_COND ((p), (rd), (imm16), ARMCOND_AL)
 
 #ifdef __cplusplus
 }
index 7a292cc92473db3b4c7430f8c57748e1919b69b9..c7affa203f38c43ab10a48ed8163e4dc50633487 100644 (file)
@@ -1,3 +1,8 @@
+2009-08-18  Christian Hergert  <chris@dronelabs.com>
+
+       * dis-cil.c:
+       * main.c: Fix printf warnings.
+
 2009-07-16  Raja R Harinath  <harinath@hurrynot.org>
 
        * get.c (get_type): Make robust to invalid types.
index cea4a6fbea920771aec0251893f92de5a37636af..52af86c5b5d4a3e8801caea8bd749d647ab3ccd0 100644 (file)
@@ -200,7 +200,7 @@ disassemble_cil (MonoImage *m, MonoMethodHeader *mh, MonoGenericContainer *conta
                                fprintf (output, "(00 00 00 00 00 00 f8 ff)"); /* NaN */
                        else {
                                char *str = stringify_double (r);
-                               fprintf (output, str);
+                               fprintf (output, "%s", str);
                                g_free (str);
                        }
                        ptr += 8;
@@ -309,7 +309,7 @@ disassemble_cil (MonoImage *m, MonoMethodHeader *mh, MonoGenericContainer *conta
                                fprintf (output, "(00 00 c0 ff)"); /* NaN */
                        else {
                                char *str = stringify_double ((double) f);
-                               fprintf (output, str);
+                               fprintf (output, "%s", str);
                                g_free (str);
                        }
                        ptr += 4;
index 61dc22cd5e1567592f19a50179352d4866f0bdc8..64af63db2dd8e8724ec3956a84f73102fab2ec1a 100644 (file)
@@ -1222,7 +1222,7 @@ dis_type (MonoImage *m, int n, int is_nested, int forward)
                
                 param = get_generic_param (m, container);
                if (param) {
-                       fprintf (output, param);
+                       fprintf (output, "%s", param);
                        g_free (param);
                }
                 fprintf (output, "\n");
@@ -1236,7 +1236,7 @@ dis_type (MonoImage *m, int n, int is_nested, int forward)
 
                 param = get_generic_param (m, container);
                if (param) {
-                       fprintf (output, param);
+                       fprintf (output, "%s", param);
                        g_free (param);
                }
                fprintf (output, "\n");
index 2dda4f5f1d5cf6e995f6035eee7a5590cbf4d13c..be13a0462231c8906e06c5af75b2906ad6577ceb 100644 (file)
@@ -1,3 +1,20 @@
+2009-08-18  Christian Hergert  <chris@dronelabs.com>
+
+       * wthreads.c: Roll back change for thread-id as it "embraces
+       and extends" the api by passing word-size for thread id on
+       s390 and amd64.
+
+2009-08-18  Christian Hergert  <chris@dronelabs.com>
+
+       * security.c:
+       * processes.c:
+       * wthreads.c: Be explicit when we are changing word sizes.
+
+2009-08-18  Christian Hergert  <chris@dronelabs.com>
+
+       * processes.c: Fix method declaration warnings.
+       * sockets.c: getsockopt() wants socklen_t for size.
+
 2009-08-04  Miguel de Icaza  <miguel@novell.com>
 
        * posix.c (_wapi_stdhandle_create): Split this into a new file to
index 19e1b9c0a8bc745d8ff1e79e7e63322fb964b92a..d162877ab868733ee0a6bf297afc9c79188badc1 100644 (file)
@@ -51,7 +51,7 @@
  * arm-apple-darwin9.  We'll manually define the symbol on Apple as it does
  * in fact exist on all implementations (so far) 
  */
-gchar ***_NSGetEnviron();
+gchar ***_NSGetEnviron(void);
 #define environ (*_NSGetEnviron())
 #else
 extern char **environ;
@@ -401,7 +401,7 @@ utf16_concat (const gunichar2 *first, ...)
 static int osx_10_5_or_higher;
 
 static void
-detect_osx_10_5_or_higher ()
+detect_osx_10_5_or_higher (void)
 {
        struct utsname u;
        char *p;
@@ -422,7 +422,7 @@ detect_osx_10_5_or_higher ()
 }
 
 static gboolean
-is_macos_10_5_or_higher ()
+is_macos_10_5_or_higher (void)
 {
        if (osx_10_5_or_higher == 0)
                detect_osx_10_5_or_higher ();
@@ -1559,7 +1559,7 @@ gpointer OpenProcess (guint32 req_access G_GNUC_UNUSED, gboolean inherit G_GNUC_
                        /* Return a pseudo handle for processes we
                         * don't have handles for
                         */
-                       return((gpointer)(_WAPI_PROCESS_UNHANDLED + pid));
+                       return GINT_TO_POINTER (_WAPI_PROCESS_UNHANDLED + pid);
                } else {
 #ifdef DEBUG
                        g_message ("%s: Can't find pid %d", __func__, pid);
@@ -1723,8 +1723,9 @@ static gint find_procmodule (gconstpointer a, gconstpointer b)
 
 #ifdef PLATFORM_MACOSX
 #include <mach-o/dyld.h>
+#include <mach-o/getsect.h>
 
-static GSList *load_modules ()
+static GSList *load_modules (void)
 {
        GSList *ret = NULL;
        WapiProcModule *mod;
@@ -1743,8 +1744,8 @@ static GSList *load_modules ()
                sec = getsectbynamefromheader (hdr, SEG_DATA, SECT_DATA);
 
                mod = g_new0 (WapiProcModule, 1);
-               mod->address_start = sec->addr;
-               mod->address_end = sec->addr+sec->size;
+               mod->address_start = GINT_TO_POINTER (sec->addr);
+               mod->address_end = GINT_TO_POINTER (sec->addr+sec->size);
                mod->perms = g_strdup ("r--p");
                mod->address_offset = 0;
                mod->device = makedev (0, 0);
index 6486839d0aa40d98650ed4ad9f1080368d619002..1d702d3188f274c02c319c8f3d59bc805d9ccbf4 100644 (file)
@@ -35,7 +35,7 @@
 gboolean 
 ImpersonateLoggedOnUser (gpointer handle)
 {
-       uid_t token = (uid_t) handle;
+       uid_t token = (uid_t) GPOINTER_TO_INT (handle);
 #ifdef HAVE_SETRESUID
        if (setresuid (-1, token, getuid ()) < 0)
                return FALSE;
index 4bc6ad28acba78e8e5f0d0305128dd1dce5a2cfd..e4f35874692054fd3b4adb320d55874df5bc13cf 100644 (file)
@@ -844,7 +844,7 @@ int _wapi_setsockopt(guint32 fd, int level, int optname,
        /* BSD's and MacOS X multicast sockets also need SO_REUSEPORT when SO_REUSEADDR is requested.  */
        if (level == SOL_SOCKET && optname == SO_REUSEADDR) {
                int type;
-               int type_len = sizeof (type);
+               socklen_t type_len = sizeof (type);
 
                if (!getsockopt (fd, level, SO_TYPE, &type, &type_len)) {
                        if (type == SOCK_DGRAM)
index 59bd9d446e3090f3b136982d6f5ec77c117ae34b..3810b82fb048e0793bd9ac38d75da481ee258ecf 100644 (file)
@@ -1,3 +1,314 @@
+2009-08-18  Rodrigo Kumpera  <rkumpera@novell.com>
+
+       * class.c (mono_class_get_field_idx): Add fixme for broken
+       behavior for types with multiple fields with the same name.
+       I would rather fix it, but have no idea on how to generate
+       such artifact for testing.
+
+2009-08-18  Rodrigo Kumpera  <rkumpera@novell.com>
+
+       * verify.c (verifier_load_field): We should allow references to
+       fields to be made using the generic type definition. It's up to
+       the loader system to fail invalid ops.
+
+       * verify.c (get_boxable_mono_type): Only uninstantiated GTDs
+       are invalid.
+
+2009-08-18  Rodrigo Kumpera  <rkumpera@novell.com>
+
+       * class.c: Fix usage of mono_metadata_interfaces_from_typedef_full.
+
+       * metadata-internals.h: Fix declaration of 
+       mono_metadata_interfaces_from_typedef_full.
+
+       * metadata.c (mono_metadata_interfaces_from_typedef_full): Add extra
+       heap_alloc_result parameter that controls if the result should be
+       g_malloc'd.
+
+       * metadata.c (mono_metadata_interfaces_from_typedef): Let the resulting
+       array be g_malloc'd and properly document this public API function.
+
+2009-08-18  Rodrigo Kumpera  <rkumpera@novell.com>
+
+       * cil-coff.h: Fix METHOD_HEADER_FORMAT_MASK to be 2 bits and
+       remove METHOD_HEADER_TINY_FORMAT1.
+
+       * reflection.c: Remove reference to METHOD_HEADER_TINY_FORMAT1.
+
+       * metadata.c (mono_metadata_parse_mh_full): Kill tiny format1.
+
+       Both spec and MS uses only 2 bits to enumerate the kind of header.
+       So given that 0x6 and 0x2 are equal under a 2 bits mask, tiny format1
+       is superfluous, only used for tiny headers with odd code lengths.
+
+       This change also make sure that mono doesn't wronly interpret bit 2
+       of fat header flags, which is currently reserved.
+
+2009-08-18  Rodrigo Kumpera  <rkumpera@novell.com>
+
+       * metadata.c (do_mono_metadata_parse_type): Do error
+       checking for element types. Don't abort if presented
+       with a broken type kind.
+
+2009-08-18  Rodrigo Kumpera  <rkumpera@novell.com>
+
+       * metadata.c (mono_metadata_parse_method_signature_full):
+       Gracefully fail bad vararg signatures.
+
+2009-08-18  Christian Hergert  <chris@dronelabs.com>
+
+       * profiler.c:
+       * class.c: Fix warnings for uninitialized variables.
+
+2009-08-18  Christian Hergert  <chris@dronelabs.com>
+
+       * icall.c: Fix _NSGetEnviron method declaration warning.
+
+2009-08-18  Christian Hergert  <chris@dronelabs.com>
+
+       * icall.c:
+       * reflection.c: Make bitwise checks explicit.
+
+2009-08-18  Christian Hergert  <chris@dronelabs.com>
+
+       * debug-helpers.c:
+       * marshal.c: Fix printf warnings.
+
+2009-08-18  Zoltan Varga  <vargaz@gmail.com>
+
+       * reflection.c (encode_cattr_value): Fix a warning.
+
+2009-08-17  Rodrigo Kumpera  <rkumpera@novell.com>
+
+       * metadata.c (mono_metadata_parse_array_full): Fix memory leak
+       of array bounds.
+
+2009-08-17  Rodrigo Kumpera  <rkumpera@novell.com>
+
+       * loader.c (mono_method_signature): Don't assert on broken
+       signature. Print a more useful error message.
+
+2009-08-17  Rodrigo Kumpera  <rkumpera@novell.com>
+
+       * loader.c (mono_method_get_marshal_info): Assert if
+       signature is invalid. Bounds check stores to the
+       mspecs array;
+
+2009-08-17  Rodrigo Kumpera  <rkumpera@novell.com>
+
+       * loader.c (field_from_memberref): Fix warning.
+
+2009-08-17  Rodrigo Kumpera  <rkumpera@novell.com>
+
+       * loader.c (mono_method_get_param_names): Check if signature
+       is null. Don't store beyond the size of the name array.
+
+2009-08-17  Rodrigo Kumpera  <rkumpera@novell.com>
+
+       * loader.c (mono_get_method_constrained): Check if signature
+       is null.
+
+2009-08-17  Rodrigo Kumpera  <rkumpera@novell.com>
+
+       * loader.c (mono_loader_set_error_bad_image): Improve
+       error messages.
+
+2009-08-17  Rodrigo Kumpera  <rkumpera@novell.com>
+
+       * loader.c (mono_get_method_full): Convert an assertion
+       into a loader error.
+
+2009-08-17  Rodrigo Kumpera  <rkumpera@novell.com>
+
+       * class-internals.h, class.c: Better naming and documentation.
+
+2009-08-17  Zoltan Varga  <vargaz@gmail.com>
+
+       * boehm-gc.c (mono_gc_add_weak_track_handle): Don't do any work if
+       obj is NULL.
+
+2009-08-14  Rodrigo Kumpera  <rkumpera@novell.com>
+
+       * loader.c (mono_method_get_signature_full): Fail gracefully if signature
+       parsing fails.
+
+2009-08-14  Rodrigo Kumpera  <rkumpera@novell.com>
+
+       * loader.c (mono_loader_error_prepare_exception): Handle missing field
+       errors with no class set.
+
+       * loader.c (field_from_memberref): If the field signature is of the wrong
+       type fail with a MissingFieldException instead of a BadImageException as
+       this is the behavior observed on MS. 
+
+2009-08-14  Rodrigo Kumpera  <rkumpera@novell.com>
+
+       * loader.c (field_from_memberref): Don't crash if either the field
+       signature or the typespec class are invalid.
+
+2009-08-14  Rodrigo Kumpera  <rkumpera@novell.com>
+
+       * verify.c (verifier_load_field): Don't allow field related
+       ops to reference fields on generic type definition.
+
+2009-08-14  Rodrigo Kumpera  <rkumpera@novell.com>
+
+       * metadata-verify.c: Add new warning level for errors specified
+       by ECMA 335 but that MS ignores.
+
+       * metadata-verify.c (verify_method_table): Make compiler controled
+       visibility + (rt)specialname error a warning as MS ignores this. Ignoring
+       this check is safe because the end result will only be some visibility
+       exceptions been thrown.
+
+2009-08-14  Rodrigo Kumpera  <rkumpera@novell.com>
+
+       * verify.c (get_boxable_mono_type): Don't allow the
+       use of the generic type definition on boxed type positions.
+
+       Fixes #531237.
+
+2009-08-14  Mark Probst  <mark.probst@gmail.com>
+
+       * threadpool.c: Make sure no cross-domain references remain in
+       ares_htable or the arrays that are thrown away when resizing.
+
+2009-08-14  Mark Probst  <mark.probst@gmail.com>
+
+       * appdomain.c, metadata-internals.h, image.c: In MonoImage add a
+       list of classes for which we have to unregister reflection_info
+       with the GC and which are not in the namespace cache.
+
+       * reflection.c (mono_reflection_initialize_generic_parameter): Add
+       the class to the list.
+
+2009-08-14  Mark Probst  <mark.probst@gmail.com>
+
+       * domain.c (mono_domain_free): Unregister the GC roots in
+       MonoDomain.
+
+2009-08-12  Rodrigo Kumpera  <rkumpera@novell.com>
+
+       * reflection.c (mono_reflection_type_get_handle): Fix typo.
+
+2009-08-12  Rodrigo Kumpera  <rkumpera@novell.com>
+
+       * class.c: Add mono_class_get_field_from_name_full which does
+       the same as mono_class_get_field_from_name but does check field
+       signature as well.
+
+       * class-internals.h: Export mono_class_get_field_from_name_full as
+       part of the internal API.
+
+       * loader.c (field_from_memberref): Search fields by name and signature
+       as it's valid to have two fields with same name but different types.
+
+       Fixes #528055.
+
+2009-08-10  Rodrigo Kumpera  <rkumpera@novell.com>
+
+       * icall-def.h: Add a bunch of temporary icalls to MonoGenericClass.
+
+       * reflection.c (mono_reflection_type_get_handle): Handle MonoGenericClass.
+
+       * reflection.c (encode_cattr_value): Use mono_reflection_type_get_handle to encode
+       System.Type.
+
+2009-08-13  Zoltan Varga  <vargaz@gmail.com>
+
+       * gc.c (GCHandle_CheckCurrentDomain): Moved this here from icall.c.
+
+       * boehm-gc.c (mono_gc_add_weak_track_handle): Handle nulls.
+
+2009-08-12  Mark Probst  <mark.probst@gmail.com>
+
+       * sgen-gc.c, sgen-scan-object.h: Object scanning code factored out
+       to sgen-scan-object.h, which can be included and parameterized via
+       macros.
+
+       * Makefile.am: sgen-scan-object.h added.
+
+2009-08-12  Mark Probst  <mark.probst@gmail.com>
+
+       * gc.c: #define GC_dont_gc if we're compiling with SGen.
+
+2009-08-12  Mark Probst  <mark.probst@gmail.com>
+
+       * domain.c (mono_domain_free): Free a domain's mono_g_hash_tables
+       before clearing a domain in the GC.
+
+2009-08-12  Mark Probst  <mark.probst@gmail.com>
+
+       * exception.c (mono_exception_from_name_domain): Actually create
+       the exception in the specified domain.
+
+       * appdomain.c (mono_domain_create_appdomain_internal): Create the
+       OutOfMemoryException a bit later so that the domain is inialized
+       "enough" that it works.
+
+2009-08-12  Mark Probst  <mark.probst@gmail.com>
+
+       * threads.c (thread_cleanup): Clean up the cached_culture_info
+       array to prevent cross-domain references.
+
+Tue Aug 11 14:38:57 CEST 2009 Paolo Molaro <lupus@ximian.com>
+
+       * metadata.c: more documentation for MonoType accessors.
+
+2009-08-11  Raja R Harinath  <harinath@hurrynot.org>
+
+       Fix incorrect size definitions where the tail array isn't a list
+       of pointers
+       * class-internals.h (MONO_SIZEOF_MARSHAL_TYPE): Use offsetof to
+       define size.
+       * domain-internals.h (MONO_SIZEOF_JIT_INFO): Likewise.
+       * metadata.h (MONO_SIZEOF_TYPE): Likewise.
+       * reflection.h (MONO_SIZEOF_CUSTOM_ATTR_INFO): Likewise.
+
+2009-08-11 Gonzalo Paniagua Javier <gonzalo@novell.com>
+
+       * reflection.h:
+       * reflection.c: MONO_SIZEOF_CUSTOM_ATTR_INFO.
+
+2009-08-11 Gonzalo Paniagua Javier <gonzalo@novell.com>
+
+       * metadata.c:
+       * loader.c:
+       * metadata-internals.h:
+       * method-builder.c:
+       * reflection.c: use MONO_SIZEOF_METHOD_HEADER.
+
+2009-08-11 Gonzalo Paniagua Javier <gonzalo@novell.com>
+
+       * cominterop.c:
+       * metadata.c:
+       * metadata.h:
+       * loader.c:
+       * marshal.c:
+       * reflection.c: #define for sizeof in MonoType and
+       MonoMethodSignature.
+
+2009-08-11 Gonzalo Paniagua Javier <gonzalo@novell.com>
+
+       * domain.c:
+       * domain-internals.h: add and use #define's instead of sizeof()
+       for MonoJitInfo and MonoJitInfoTable.
+
+2009-08-11 Gonzalo Paniagua Javier <gonzalo@novell.com>
+
+       * object.c:
+       * class.h: use #define instead of sizeof() for MonoRemoteClass.
+
+2009-08-10 Gonzalo Paniagua Javier <gonzalo@novell.com>
+
+       * metadata.c:
+       * metadata.h:
+       * object.c:
+       * class-internals.h:
+       * generic-sharing.c:
+       * marshal.c: use a #define instead of sizeof() for a few
+       structures that use a zero-length array.
+
 2009-08-06  Rodrigo Kumpera  <rkumpera@novell.com>
 
        * object-internals.h (MonoReflectionMethodOnTypeBuilderInst): Add new fields
index 6165421d0e00f0f6887b536e7f82a399ef829199..0eb0effc76e9b3cc02124a84121b92746c10aecf 100644 (file)
@@ -147,6 +147,7 @@ libmonoruntime_la_SOURCES = \
        sgen-gc.c               \
        sgen-gc.h               \
        sgen-archdep.h          \
+       sgen-scan-object.h      \
        string-icalls.c         \
        string-icalls.h         \
        sysmath.h               \
index 8a887a631316631d1ae41393dd222568ff01f764..2858dd77e41137b02b0842e22ca24f54a68eda44 100644 (file)
@@ -414,9 +414,6 @@ mono_domain_create_appdomain_internal (char *friendly_name, MonoAppDomainSetup *
        data->domain = ad;
        data->setup = setup;
        data->friendly_name = g_strdup (friendly_name);
-       // FIXME: The ctor runs in the current domain
-       // FIXME: Initialize null_reference_ex and stack_overflow_ex
-       data->out_of_memory_ex = mono_exception_from_name_domain (data, mono_defaults.corlib, "System", "OutOfMemoryException");
 
        if (!setup->application_base) {
                /* Inherit from the root domain since MS.NET does this */
@@ -436,7 +433,10 @@ mono_domain_create_appdomain_internal (char *friendly_name, MonoAppDomainSetup *
        mono_debugger_event_create_appdomain (data, shadow_location);
        g_free (shadow_location);
 #endif
-       
+
+       // FIXME: Initialize null_reference_ex and stack_overflow_ex
+       data->out_of_memory_ex = mono_exception_from_name_domain (data, mono_defaults.corlib, "System", "OutOfMemoryException");
+
        return ad;
 }
 
@@ -1991,6 +1991,24 @@ deregister_reflection_info_roots_name_space (gpointer key, gpointer value, gpoin
        g_hash_table_foreach (value, deregister_reflection_info_roots_nspace_table, user_data);
 }
 
+static void
+deregister_reflection_info_roots_from_list (MonoImage *image)
+{
+       GSList *list = image->reflection_info_unregister_classes;
+
+       while (list) {
+               MonoClass *class = list->data;
+
+               g_assert (class->reflection_info);
+               mono_gc_deregister_root ((char*) &class->reflection_info);
+
+               list = list->next;
+       }
+
+       g_slist_free (image->reflection_info_unregister_classes);
+       image->reflection_info_unregister_classes = NULL;
+}
+
 static void
 deregister_reflection_info_roots (MonoDomain *domain)
 {
@@ -2005,10 +2023,16 @@ deregister_reflection_info_roots (MonoDomain *domain)
                /*No need to take the image lock here since dynamic images are appdomain bound and at this point the mutator is gone.*/
                if (image->dynamic && image->name_cache)
                        g_hash_table_foreach (image->name_cache, deregister_reflection_info_roots_name_space, image);
+               deregister_reflection_info_roots_from_list (image);
                for (i = 0; i < image->module_count; ++i) {
                        MonoImage *module = image->modules [i];
-                       if (module && module->dynamic && module->name_cache)
-                               g_hash_table_foreach (module->name_cache, deregister_reflection_info_roots_name_space, module);
+                       if (module) {
+                               if (module->dynamic && module->name_cache) {
+                                       g_hash_table_foreach (module->name_cache,
+                                                       deregister_reflection_info_roots_name_space, module);
+                               }
+                               deregister_reflection_info_roots_from_list (module);
+                       }
                }
        }
        mono_domain_assemblies_unlock (domain);
index 735b5217f4e35ef922ff1f777ca7bd61b39d1dc3..58a2173e40e227dcd66d03bbaa4182516930c4a7 100644 (file)
@@ -425,7 +425,12 @@ add_weak_track_handle_internal (MonoDomain *domain, MonoObject *obj, guint32 gch
 void
 mono_gc_add_weak_track_handle (MonoObject *obj, guint32 handle)
 {
-       MonoDomain *domain = mono_object_get_domain (obj);
+       MonoDomain *domain;
+
+       if (!obj)
+               return;
+
+       domain = mono_object_get_domain (obj);
 
        mono_domain_finalizers_lock (domain);
 
index 1a3ff48f06f66c94440586b4374cb762b8c71674..290b85dc718436d1db63ae6462928fc067773667 100644 (file)
@@ -7,9 +7,8 @@
 /*
  * 25.2.1: Method header type values
  */
-#define METHOD_HEADER_FORMAT_MASK   7
+#define METHOD_HEADER_FORMAT_MASK   3
 #define METHOD_HEADER_TINY_FORMAT   2
-#define METHOD_HEADER_TINY_FORMAT1  6
 #define METHOD_HEADER_FAT_FORMAT    3
 
 /*
index 5a5476138dc7dab79bc462e51306f1f4bd6896d8..30b113ae7c4c49a10d90ef1c1422fcb2f748b4c7 100644 (file)
@@ -161,6 +161,8 @@ typedef struct {
        MonoMarshalField fields [MONO_ZERO_LEN_ARRAY];
 } MonoMarshalType;
 
+#define MONO_SIZEOF_MARSHAL_TYPE (offsetof (MonoMarshalType, fields))
+
 struct _MonoProperty {
        MonoClass *parent;
        const char *name;
@@ -207,6 +209,8 @@ typedef struct {
        MonoVTable *domain_vtables [MONO_ZERO_LEN_ARRAY];
 } MonoClassRuntimeInfo;
 
+#define MONO_SIZEOF_CLASS_RUNTIME_INFO (sizeof (MonoClassRuntimeInfo) - MONO_ZERO_LEN_ARRAY * SIZEOF_VOID_P)
+
 enum {
        MONO_RGCTX_INFO_STATIC_DATA,
        MONO_RGCTX_INFO_KLASS,
@@ -239,6 +243,8 @@ typedef struct {
        gpointer infos [MONO_ZERO_LEN_ARRAY];
 } MonoMethodRuntimeGenericContext;
 
+#define MONO_SIZEOF_METHOD_RUNTIME_GENERIC_CONTEXT (sizeof (MonoMethodRuntimeGenericContext) - MONO_ZERO_LEN_ARRAY * SIZEOF_VOID_P)
+
 #define MONO_RGCTX_SLOT_MAKE_RGCTX(i)  (i)
 #define MONO_RGCTX_SLOT_MAKE_MRGCTX(i) ((i) | 0x80000000)
 #define MONO_RGCTX_SLOT_INDEX(s)       ((s) & 0x7fffffff)
@@ -436,6 +442,8 @@ struct MonoVTable {
         gpointer    vtable [MONO_ZERO_LEN_ARRAY];      
 };
 
+#define MONO_SIZEOF_VTABLE (sizeof (MonoVTable) - MONO_ZERO_LEN_ARRAY * SIZEOF_VOID_P)
+
 #define MONO_VTABLE_IMPLEMENTS_INTERFACE(vt,uiid) (((uiid) <= (vt)->max_interface_id) && ((vt)->interface_bitmap [(uiid) >> 3] & (1 << ((uiid)&7))))
 
 /*
@@ -455,6 +463,7 @@ struct _MonoGenericInst {
        MonoType *type_argv [MONO_ZERO_LEN_ARRAY];
 };
 
+#define MONO_SIZEOF_GENERIC_INST (sizeof (MonoGenericInst) - MONO_ZERO_LEN_ARRAY * SIZEOF_VOID_P)
 /*
  * The generic context: an instantiation of a set of class and method generic parameters.
  *
@@ -1223,4 +1232,7 @@ mono_class_alloc_ext (MonoClass *klass) MONO_INTERNAL;
 void
 mono_class_setup_interfaces (MonoClass *klass) MONO_INTERNAL;
 
+MonoClassField*
+mono_class_get_field_from_name_full (MonoClass *klass, const char *name, MonoType *type) MONO_INTERNAL;
+
 #endif /* __MONO_METADATA_CLASS_INTERBALS_H__ */
index 5e6776f19d8fe925200fc34bea9a3a85f5bd377b..17086e0a1ac53ca6ffc5f7917471a01b4daa5157 100644 (file)
@@ -4323,7 +4323,7 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token)
 
        if (!class->enumtype) {
                if (!mono_metadata_interfaces_from_typedef_full (
-                           image, type_token, &interfaces, &icount, context)){
+                           image, type_token, &interfaces, &icount, FALSE, context)){
                        mono_loader_unlock ();
                        mono_profiler_class_loaded (class, MONO_PROFILE_FAILED);
                        return NULL;
@@ -4912,7 +4912,7 @@ mono_bounded_array_class_get (MonoClass *eclass, guint32 rank, gboolean bounded)
        MonoImage *image;
        MonoClass *class;
        MonoClass *parent = NULL;
-       GSList *list, *rootlist;
+       GSList *list, *rootlist = NULL;
        int nsize;
        char *name;
        gboolean corlib_type = FALSE;
@@ -5171,6 +5171,7 @@ mono_class_get_field_idx (MonoClass *class, int idx)
                         * class->field.first points to the FieldPtr table, while idx points into the
                         * Field table, so we have to do a search.
                         */
+                       /*FIXME this is broken for types with multiple fields with the same name.*/
                        const char *name = mono_metadata_string_heap (class->image, mono_metadata_decode_row_col (&class->image->tables [MONO_TABLE_FIELD], idx, MONO_FIELD_NAME));
                        int i;
 
@@ -5220,14 +5221,42 @@ mono_class_get_field (MonoClass *class, guint32 field_token)
  */
 MonoClassField *
 mono_class_get_field_from_name (MonoClass *klass, const char *name)
+{
+       return mono_class_get_field_from_name_full (klass, name, NULL);
+}
+
+/**
+ * mono_class_get_field_from_name_full:
+ * @klass: the class to lookup the field.
+ * @name: the field name
+ * @type: the type of the fields. This optional.
+ *
+ * Search the class @klass and it's parents for a field with the name @name and type @type.
+ *
+ * If @klass is an inflated generic type, the type comparison is done with the equivalent field
+ * of its generic type definition.
+ *
+ * Returns: the MonoClassField pointer of the named field or NULL
+ */
+MonoClassField *
+mono_class_get_field_from_name_full (MonoClass *klass, const char *name, MonoType *type)
 {
        int i;
 
        mono_class_setup_fields_locking (klass);
        while (klass) {
                for (i = 0; i < klass->field.count; ++i) {
-                       if (strcmp (name, mono_field_get_name (&klass->fields [i])) == 0)
-                               return &klass->fields [i];
+                       MonoClassField *field = &klass->fields [i];
+
+                       if (strcmp (name, mono_field_get_name (field)) != 0)
+                               continue;
+
+                       if (type) {
+                               MonoType *field_type = mono_metadata_get_corresponding_field_from_generic_type_definition (field)->type;
+                               if (!mono_metadata_type_equal_full (type, field_type, TRUE))
+                                       continue;
+                       }
+                       return field;
                }
                klass = klass->parent;
        }
index 471967a4ea2cac991e949ed5a8220637677df655..a1dc03355413b9703b73024899a14e18642501d4 100644 (file)
@@ -22,6 +22,8 @@ typedef struct {
        MonoClass *interfaces [MONO_ZERO_LEN_ARRAY];
 } MonoRemoteClass;
 
+#define MONO_SIZEOF_REMOTE_CLASS (sizeof (MonoRemoteClass) - MONO_ZERO_LEN_ARRAY * SIZEOF_VOID_P)
+
 MonoClass *
 mono_class_get             (MonoImage *image, guint32 type_token);
 
index d1052239cf6f1862ee1bf2892b94eebc9fd602eb..6e945793e97bd099fd05ea6ad02e22fe94727c02 100644 (file)
@@ -160,7 +160,7 @@ cominterop_method_signature (MonoMethod* method)
                param_count++;
 
        res = mono_metadata_signature_alloc (image, param_count);
-       sigsize = sizeof (MonoMethodSignature) + ((sig->param_count - MONO_ZERO_LEN_ARRAY) * sizeof (MonoType *));
+       sigsize = MONO_SIZEOF_METHOD_SIGNATURE + sig->param_count * sizeof (MonoType *);
        memcpy (res, sig, sigsize);
 
        // now move args forward one
index 5f6d509290fabdaf29c4ad1ee0bd64bef282fe3d..79f5296af8ebfc29abafb1b2cd36a53fcfcfffe1 100644 (file)
@@ -752,11 +752,11 @@ print_name_space (MonoClass *klass)
 {
        if (klass->nested_in) {
                print_name_space (klass->nested_in);
-               g_print (klass->nested_in->name);
+               g_print ("%s", klass->nested_in->name);
                return "/";
        }
        if (klass->name_space [0]) {
-               g_print (klass->name_space);
+               g_print ("%s", klass->name_space);
                return ".";
        }
        return "";
index bb267cdf85a17a5ddd93ac0ab9185c40bad295fe..1c4a01c56593c160ea2b48dcfc7ce41eba065167 100644 (file)
@@ -69,6 +69,8 @@ struct _MonoJitInfoTable
        MonoJitInfoTableChunk  *chunks [MONO_ZERO_LEN_ARRAY];
 };
 
+#define MONO_SIZEOF_JIT_INFO_TABLE (sizeof (struct _MonoJitInfoTable) - MONO_ZERO_LEN_ARRAY * SIZEOF_VOID_P)
+
 typedef GArray MonoAotModuleInfoTable;
 
 typedef struct {
@@ -132,6 +134,8 @@ struct _MonoJitInfo {
        /* There is an optional MonoGenericJitInfo after the clauses */
 };
 
+#define MONO_SIZEOF_JIT_INFO (offsetof (struct _MonoJitInfo, clauses))
+
 struct _MonoAppContext {
        MonoObject obj;
        gint32 domain_id;
index ebe13ad5568b4122f417702af92ce394563b8917..6a8d599b82d578b94998d9688173b19310c99002 100644 (file)
@@ -222,7 +222,7 @@ jit_info_table_new_chunk (void)
 static MonoJitInfoTable *
 jit_info_table_new (MonoDomain *domain)
 {
-       MonoJitInfoTable *table = g_malloc0 (sizeof (MonoJitInfoTable) + sizeof (MonoJitInfoTableChunk*));
+       MonoJitInfoTable *table = g_malloc0 (MONO_SIZEOF_JIT_INFO_TABLE + sizeof (MonoJitInfoTableChunk*));
 
        table->domain = domain;
        table->num_chunks = 1;
@@ -507,7 +507,7 @@ jit_info_table_realloc (MonoJitInfoTable *old)
        required_size = (int)((long)num_elements * JIT_INFO_TABLE_FILL_RATIO_DENOM / JIT_INFO_TABLE_FILL_RATIO_NOM);
        num_chunks = (required_size + MONO_JIT_INFO_TABLE_CHUNK_SIZE - 1) / MONO_JIT_INFO_TABLE_CHUNK_SIZE;
 
-       new = g_malloc (sizeof (MonoJitInfoTable) + sizeof (MonoJitInfoTableChunk*) * num_chunks);
+       new = g_malloc (MONO_SIZEOF_JIT_INFO_TABLE + sizeof (MonoJitInfoTableChunk*) * num_chunks);
        new->domain = old->domain;
        new->num_chunks = num_chunks;
 
@@ -576,7 +576,7 @@ jit_info_table_split_chunk (MonoJitInfoTableChunk *chunk, MonoJitInfoTableChunk
 static MonoJitInfoTable*
 jit_info_table_copy_and_split_chunk (MonoJitInfoTable *table, MonoJitInfoTableChunk *chunk)
 {
-       MonoJitInfoTable *new_table = g_malloc (sizeof (MonoJitInfoTable)
+       MonoJitInfoTable *new_table = g_malloc (MONO_SIZEOF_JIT_INFO_TABLE
                + sizeof (MonoJitInfoTableChunk*) * (table->num_chunks + 1));
        int i, j;
 
@@ -624,7 +624,7 @@ jit_info_table_purify_chunk (MonoJitInfoTableChunk *old)
 static MonoJitInfoTable*
 jit_info_table_copy_and_purify_chunk (MonoJitInfoTable *table, MonoJitInfoTableChunk *chunk)
 {
-       MonoJitInfoTable *new_table = g_malloc (sizeof (MonoJitInfoTable)
+       MonoJitInfoTable *new_table = g_malloc (MONO_SIZEOF_JIT_INFO_TABLE
                + sizeof (MonoJitInfoTableChunk*) * table->num_chunks);
        int i, j;
 
@@ -1879,12 +1879,44 @@ mono_domain_free (MonoDomain *domain, gboolean force)
 
        mono_debug_domain_unload (domain);
 
-       mono_gc_clear_domain (domain);
-
        mono_appdomains_lock ();
        appdomains_list [domain->domain_id] = NULL;
        mono_appdomains_unlock ();
 
+       /*
+        * We must destroy all these hash tables here because they
+        * contain references to managed objects belonging to the
+        * domain.  Once we let the GC clear the domain there must be
+        * no more such references, or we'll crash if a collection
+        * occurs.
+        */
+       mono_g_hash_table_destroy (domain->ldstr_table);
+       domain->ldstr_table = NULL;
+
+       mono_g_hash_table_destroy (domain->env);
+       domain->env = NULL;
+
+       mono_reflection_cleanup_domain (domain);
+
+       if (domain->type_hash) {
+               mono_g_hash_table_destroy (domain->type_hash);
+               domain->type_hash = NULL;
+       }
+       if (domain->type_init_exception_hash) {
+               mono_g_hash_table_destroy (domain->type_init_exception_hash);
+               domain->type_init_exception_hash = NULL;
+       }
+
+       for (tmp = domain->domain_assemblies; tmp; tmp = tmp->next) {
+               MonoAssembly *ass = tmp->data;
+               mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Unloading domain %s %p, assembly %s %p, refcount=%d\n", domain->friendly_name, domain, ass->aname.name, ass, ass->ref_count);
+               mono_assembly_close (ass);
+       }
+       g_slist_free (domain->domain_assemblies);
+       domain->domain_assemblies = NULL;
+
+       mono_gc_clear_domain (domain);
+
        /* FIXME: free delegate_hash_table when it's used */
        if (domain->search_path) {
                g_strfreev (domain->search_path);
@@ -1903,18 +1935,9 @@ mono_domain_free (MonoDomain *domain, gboolean force)
                g_hash_table_destroy (domain->special_static_fields);
                domain->special_static_fields = NULL;
        }
-       for (tmp = domain->domain_assemblies; tmp; tmp = tmp->next) {
-               MonoAssembly *ass = tmp->data;
-               mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Unloading domain %s %p, assembly %s %p, refcount=%d\n", domain->friendly_name, domain, ass->aname.name, ass, ass->ref_count);
-               mono_assembly_close (ass);
-       }
-       g_slist_free (domain->domain_assemblies);
-       domain->domain_assemblies = NULL;
 
        g_free (domain->friendly_name);
        domain->friendly_name = NULL;
-       mono_g_hash_table_destroy (domain->env);
-       domain->env = NULL;
        g_hash_table_destroy (domain->class_vtable_hash);
        domain->class_vtable_hash = NULL;
        g_hash_table_destroy (domain->proxy_vtable_hash);
@@ -1924,8 +1947,6 @@ mono_domain_free (MonoDomain *domain, gboolean force)
                domain->static_data_array = NULL;
        }
        mono_internal_hash_table_destroy (&domain->jit_code_hash);
-       mono_g_hash_table_destroy (domain->ldstr_table);
-       domain->ldstr_table = NULL;
 
        /*
         * There might still be jit info tables of this domain which
@@ -1955,16 +1976,6 @@ mono_domain_free (MonoDomain *domain, gboolean force)
        domain->code_mp = NULL;
 #endif 
 
-       mono_reflection_cleanup_domain (domain);
-       
-       if (domain->type_hash) {
-               mono_g_hash_table_destroy (domain->type_hash);
-               domain->type_hash = NULL;
-       }
-       if (domain->type_init_exception_hash) {
-               mono_g_hash_table_destroy (domain->type_init_exception_hash);
-               domain->type_init_exception_hash = NULL;
-       }
        g_hash_table_destroy (domain->finalizable_objects_hash);
        domain->finalizable_objects_hash = NULL;
 #ifndef HAVE_SGEN_GC
@@ -1990,6 +2001,8 @@ mono_domain_free (MonoDomain *domain, gboolean force)
        DeleteCriticalSection (&domain->lock);
        domain->setup = NULL;
 
+       mono_gc_deregister_root ((char*)&(domain->MONO_DOMAIN_FIRST_GC_TRACKED));
+
        /* FIXME: anything else required ? */
 
        mono_profiler_appdomain_event (domain, MONO_PROFILE_END_UNLOAD);
index 2fe196762ebb8e37cb2dc08822996fbcb73a6d5a..c20c65f661ea3a771da3a58d4217b662bf6868b9 100644 (file)
@@ -52,13 +52,18 @@ mono_exception_from_name_domain (MonoDomain *domain, MonoImage *image,
 {
        MonoClass *klass;
        MonoObject *o;
+       MonoDomain *caller_domain = mono_domain_get ();
 
        klass = mono_class_from_name (image, name_space, name);
 
        o = mono_object_new (domain, klass);
        g_assert (o != NULL);
-       
+
+       if (domain != caller_domain)
+               mono_domain_set_internal (domain);
        mono_runtime_object_init (o);
+       if (domain != caller_domain)
+               mono_domain_set_internal (caller_domain);
 
        return (MonoException *)o;
 }
index 56aff2938dd51f86552052e375d40e8f3304d025..f80180ec06c2ef71b971c8da4915fe18bf35cb6e 100644 (file)
@@ -71,6 +71,9 @@ void    mono_gc_remove_weak_track_handle (guint32 gchandle) MONO_INTERNAL;
 GSList* mono_gc_remove_weak_track_object (MonoDomain *domain, MonoObject *obj) MONO_INTERNAL;
 #endif
 
+MonoBoolean
+GCHandle_CheckCurrentDomain (guint32 gchandle) MONO_INTERNAL;
+
 /* simple interface for data structures needed in the runtime */
 void* mono_gc_make_descr_from_bitmap (gsize *bitmap, int numbits) MONO_INTERNAL;
 
index e5c32bae0ccb76d06cbf4ccfd4b353491f593eeb..54dffb3865c4d2db6668c2c531091eb4d5ac559c 100644 (file)
@@ -908,6 +908,12 @@ mono_gchandle_free_domain (MonoDomain *domain)
 
 }
 
+MonoBoolean
+GCHandle_CheckCurrentDomain (guint32 gchandle)
+{
+       return mono_gchandle_is_in_domain (gchandle, mono_domain_get ());
+}
+
 #ifndef HAVE_NULL_GC
 
 #ifdef MONO_HAS_SEMAPHORES
@@ -1040,6 +1046,10 @@ finalizer_thread (gpointer unused)
        return 0;
 }
 
+#ifdef HAVE_SGEN_GC
+#define GC_dont_gc 0
+#endif
+
 void
 mono_gc_init (void)
 {
index 152cb107e1925f24267452ac4014d7a73693b5ed..47b5a370f9c737f80a68ebb145920c6fa1d2934d 100644 (file)
@@ -1086,12 +1086,12 @@ fill_runtime_generic_context (MonoVTable *class_vtable, MonoRuntimeGenericContex
        first_slot = 0;
        size = mono_class_rgctx_get_array_size (0, method_inst != NULL);
        if (method_inst)
-               size -= sizeof (MonoMethodRuntimeGenericContext) / sizeof (gpointer);
+               size -= MONO_SIZEOF_METHOD_RUNTIME_GENERIC_CONTEXT / sizeof (gpointer);
        for (i = 0; ; ++i) {
                int offset;
 
                if (method_inst && i == 0)
-                       offset = sizeof (MonoMethodRuntimeGenericContext) / sizeof (gpointer);
+                       offset = MONO_SIZEOF_METHOD_RUNTIME_GENERIC_CONTEXT / sizeof (gpointer);
                else
                        offset = 0;
 
index 4341a5a52f8e40c9fc4b648e2e1f327b501c16a3..c2f69a69d0e81f07441e84f1ad375de563b4609a 100644 (file)
@@ -600,6 +600,7 @@ ICALL(MGENCL_1, "GetConstructors_internal", ves_icall_MonoGenericClass_GetConstr
 ICALL(MGENCL_2, "GetCorrespondingInflatedConstructor", ves_icall_MonoGenericClass_GetCorrespondingInflatedConstructor)
 ICALL(MGENCL_3, "GetCorrespondingInflatedField", ves_icall_MonoGenericClass_GetCorrespondingInflatedField)
 ICALL(MGENCL_4, "GetCorrespondingInflatedMethod", ves_icall_MonoGenericClass_GetCorrespondingInflatedMethod)
+ICALL(MGENCL_16, "GetElementType", ves_icall_MonoType_GetElementType)
 ICALL(MGENCL_5, "GetEvents_internal", ves_icall_MonoGenericClass_GetEvents)
 ICALL(MGENCL_6, "GetFields_internal", ves_icall_MonoGenericClass_GetFields)
 ICALL(MGENCL_7, "GetInterfaces_internal", ves_icall_MonoGenericClass_GetInterfaces)
@@ -607,6 +608,9 @@ ICALL(MGENCL_8, "GetMethods_internal", ves_icall_MonoGenericClass_GetMethods)
 ICALL(MGENCL_9, "GetParentType", ves_icall_MonoGenericClass_GetParentType)
 ICALL(MGENCL_10, "GetProperties_internal", ves_icall_MonoGenericClass_GetProperties)
 ICALL(MGENCL_12, "InflateType_internal", ves_icall_MonoGenericClass_InflateType)
+ICALL(MGENCL_13, "IsByRefImpl", ves_icall_type_isbyref)
+ICALL(MGENCL_14, "IsPointerImpl", ves_icall_type_ispointer)
+ICALL(MGENCL_15, "IsPrimitiveImpl", ves_icall_type_isprimitive)
 ICALL(MGENCL_11, "initialize", mono_reflection_generic_class_initialize)
 
 /* note this is the same as above: unify */
index a8d28707c5ec9d914fe2b5a43c80f024548d5e75..c163adee288bd6a5ad41eb79cb9d9ea8864b93ee 100644 (file)
@@ -2938,7 +2938,7 @@ ves_icall_MonoMethod_GetDllImportAttribute (MonoMethod *method)
        const char *scope = NULL;
        guint32 flags;
 
-       if (!method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)
+       if (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
                return NULL;
 
        if (!DllImportAttributeClass) {
@@ -6556,7 +6556,7 @@ ves_icall_System_Environment_GetEnvironmentVariable (MonoString *name)
  * arm-apple-darwin9.  We'll manually define the symbol on Apple as it does
  * in fact exist on all implementations (so far) 
  */
-gchar ***_NSGetEnviron();
+gchar ***_NSGetEnviron(void);
 #define environ (*_NSGetEnviron())
 #else
 extern
@@ -7560,12 +7560,6 @@ custom_attrs_get_by_type (MonoObject *obj, MonoReflectionType *attr_type)
        }
 }
 
-static MonoBoolean
-GCHandle_CheckCurrentDomain (guint32 gchandle)
-{
-       return mono_gchandle_is_in_domain (gchandle, mono_domain_get ());
-}
-
 static MonoString*
 ves_icall_Mono_Runtime_GetDisplayName (void)
 {
index 47e85ea3690f288ec47d69d71eecf955f1c90f19..e6312b4d71454089f839c970899671623bd4d091 100644 (file)
@@ -1555,6 +1555,8 @@ mono_image_close (MonoImage *image)
        if (image->property_hash)
                mono_property_hash_destroy (image->property_hash);
 
+       g_slist_free (image->reflection_info_unregister_classes);
+
        if (image->interface_bitset) {
                mono_unload_interface_ids (image->interface_bitset);
                mono_bitset_free (image->interface_bitset);
index 6fd64a2979ff920d5bd41ecefbe4e76ea92f4892..bca32e362f80ba578487a982d3f70d146be99443 100644 (file)
@@ -306,8 +306,8 @@ mono_loader_error_prepare_exception (MonoLoaderError *error)
        }
                
        case MONO_EXCEPTION_MISSING_FIELD: {
-               char *cnspace = g_strdup (*error->klass->name_space ? error->klass->name_space : "");
-               char *cname = g_strdup (error->klass->name);
+               char *cnspace = g_strdup ((error->klass && *error->klass->name_space) ? error->klass->name_space : "");
+               char *cname = g_strdup (error->klass ? error->klass->name : "");
                char *cmembername = g_strdup (error->member_name);
                 char *class_name;
 
@@ -405,7 +405,7 @@ field_from_memberref (MonoImage *image, guint32 token, MonoClass **retklass,
                      MonoGenericContext *context)
 {
        MonoClass *klass;
-       MonoClassField *field, *sig_field = NULL;
+       MonoClassField *field;
        MonoTableInfo *tables = image->tables;
        MonoType *sig_type;
        guint32 cols[6];
@@ -430,7 +430,8 @@ field_from_memberref (MonoImage *image, guint32 token, MonoClass **retklass,
        /* we may want to check the signature here... */
 
        if (*ptr++ != 0x6) {
-               mono_loader_set_error_bad_image (g_strdup_printf ("Bad field signature class token %08x field name %s token %08x", class, fname, token));
+               g_warning ("Bad field signature class token %08x field name %s token %08x", class, fname, token);
+               mono_loader_set_error_field_load (NULL, fname);
                return NULL;
        }
        /* FIXME: This needs a cache, especially for generic instances, since
@@ -439,6 +440,10 @@ field_from_memberref (MonoImage *image, guint32 token, MonoClass **retklass,
        sig_type = find_cached_memberref_sig (image, cols [MONO_MEMBERREF_SIGNATURE]);
        if (!sig_type) {
                sig_type = mono_metadata_parse_type (image, MONO_PARSE_TYPE, 0, ptr, &ptr);
+               if (sig_type == NULL) {
+                       mono_loader_set_error_field_load (NULL, fname);
+                       return NULL;
+               }
                sig_type = cache_memberref_sig (image, cols [MONO_MEMBERREF_SIGNATURE], sig_type);
        }
 
@@ -455,7 +460,7 @@ field_from_memberref (MonoImage *image, guint32 token, MonoClass **retklass,
                mono_class_init (klass);
                if (retklass)
                        *retklass = klass;
-               sig_field = field = mono_class_get_field_from_name (klass, fname);
+               field = mono_class_get_field_from_name_full (klass, fname, sig_type);
                break;
        case MONO_MEMBERREF_PARENT_TYPEREF:
                klass = mono_class_from_typeref (image, MONO_TOKEN_TYPE_REF | nindex);
@@ -469,17 +474,21 @@ field_from_memberref (MonoImage *image, guint32 token, MonoClass **retklass,
                mono_class_init (klass);
                if (retklass)
                        *retklass = klass;
-               sig_field = field = mono_class_get_field_from_name (klass, fname);
+               field = mono_class_get_field_from_name_full (klass, fname, sig_type);
                break;
        case MONO_MEMBERREF_PARENT_TYPESPEC: {
                klass = mono_class_get_full (image, MONO_TOKEN_TYPE_SPEC | nindex, context);
-               //FIXME can't klass be null?
+               if (!klass) {
+                       char *name = mono_class_name_from_token (image, MONO_TOKEN_TYPE_REF | nindex);
+                       g_warning ("missing field %s in class %s (typeref index %d)", fname, name, nindex);
+                       mono_loader_set_error_type_load (name, image->assembly_name);
+                       g_free (name);
+                       return NULL;
+               }
                mono_class_init (klass);
                if (retklass)
                        *retklass = klass;
-               field = mono_class_get_field_from_name (klass, fname);
-               if (field)
-                       sig_field = mono_metadata_get_corresponding_field_from_generic_type_definition (field);
+               field = mono_class_get_field_from_name_full (klass, fname, sig_type);
                break;
        }
        default:
@@ -489,10 +498,6 @@ field_from_memberref (MonoImage *image, guint32 token, MonoClass **retklass,
 
        if (!field)
                mono_loader_set_error_field_load (klass, fname);
-       else if (sig_field && !mono_metadata_type_equal_full (sig_type, sig_field->type, TRUE)) {
-               mono_loader_set_error_field_load (klass, fname);
-               return NULL;
-       }
 
        return field;
 }
@@ -704,7 +709,7 @@ inflate_generic_signature (MonoImage *image, MonoMethodSignature *sig, MonoGener
        if (!context)
                return sig;
 
-       res = g_malloc0 (sizeof (MonoMethodSignature) + ((gint32)sig->param_count - MONO_ZERO_LEN_ARRAY) * sizeof (MonoType*));
+       res = g_malloc0 (MONO_SIZEOF_METHOD_SIGNATURE + ((gint32)sig->param_count) * sizeof (MonoType*));
        res->param_count = sig->param_count;
        res->sentinelpos = -1;
        res->ret = mono_class_inflate_generic_type (sig->ret, context);
@@ -730,7 +735,7 @@ inflate_generic_header (MonoMethodHeader *header, MonoGenericContext *context)
 {
        MonoMethodHeader *res;
        int i;
-       res = g_malloc0 (sizeof (MonoMethodHeader) + sizeof (gpointer) * header->num_locals);
+       res = g_malloc0 (MONO_SIZEOF_METHOD_HEADER + sizeof (gpointer) * header->num_locals);
        res->code = header->code;
        res->code_size = header->code_size;
        res->max_stack = header->max_stack;
@@ -753,7 +758,7 @@ inflate_generic_header (MonoMethodHeader *header, MonoGenericContext *context)
 }
 
 /*
- * token is the method_ref or method_def token used in a call IL instruction.
+ * token is the method_ref/def/spec token used in a call IL instruction.
  */
 MonoMethodSignature*
 mono_method_get_signature_full (MonoMethod *method, MonoImage *image, guint32 token, MonoGenericContext *context)
@@ -800,7 +805,8 @@ mono_method_get_signature_full (MonoMethod *method, MonoImage *image, guint32 to
                ptr = mono_metadata_blob_heap (image, sig_idx);
                mono_metadata_decode_blob_size (ptr, &ptr);
                sig = mono_metadata_parse_method_signature (image, 0, ptr, NULL);
-
+               if (!sig)
+                       return NULL;
                sig = cache_memberref_sig (image, sig_idx, sig);
        }
 
@@ -1449,7 +1455,7 @@ mono_get_method_from_token (MonoImage *image, guint32 token, MonoClass *klass,
                result = mono_lookup_dynamic_token_class (image, token, TRUE, &handle_class, context);
                // This checks the memberref type as well
                if (result && handle_class != mono_defaults.methodhandle_class) {
-                       mono_loader_set_error_bad_image (g_strdup ("Bad method token."));
+                       mono_loader_set_error_bad_image (g_strdup_printf ("Bad method token 0x%08x on image %s.", token, image->name));
                        return NULL;
                }
                return result;
@@ -1460,16 +1466,18 @@ mono_get_method_from_token (MonoImage *image, guint32 token, MonoClass *klass,
                        if (used_context) *used_context = TRUE;
                        return method_from_methodspec (image, context, idx);
                }
-               if (table != MONO_TABLE_MEMBERREF)
-                       g_print("got wrong token: 0x%08x\n", token);
-               g_assert (table == MONO_TABLE_MEMBERREF);
+               if (table != MONO_TABLE_MEMBERREF) {
+                       g_warning ("got wrong token: 0x%08x\n", token);
+                       mono_loader_set_error_bad_image (g_strdup_printf ("Bad method token 0x%08x on image %s.", token, image->name));
+                       return NULL;
+               }
                return method_from_memberref (image, idx, context, used_context);
        }
 
        if (used_context) *used_context = FALSE;
 
        if (idx > image->tables [MONO_TABLE_METHOD].rows) {
-               mono_loader_set_error_bad_image (g_strdup ("Bad method token."));
+               mono_loader_set_error_bad_image (g_strdup_printf ("Bad method token 0x%08x on image %s.", token, image->name));
                return NULL;
        }
 
@@ -1639,17 +1647,19 @@ mono_get_method_constrained (MonoImage *image, guint32 token, MonoClass *constra
        mono_class_init (constrained_class);
        method = *cil_method;
        original_sig = sig = mono_method_signature (method);
+       if (sig == NULL)
+               return NULL;
 
        if (method->is_inflated && sig->generic_param_count) {
                MonoMethodInflated *imethod = (MonoMethodInflated *) method;
-               sig = mono_method_signature (imethod->declaring);
+               sig = mono_method_signature (imethod->declaring); /*We assume that if the inflated method signature is valid, the declaring method is too*/
                method_context = mono_method_get_context (method);
 
                original_sig = sig;
                /*
                 * We must inflate the signature with the class instantiation to work on
                 * cases where a class inherit from a generic type and the override replaces
-                * and type argument which a concrete type. See #325283.
+                * any type argument which a concrete type. See #325283.
                 */
                if (method_context->class_inst) {
                        MonoGenericContext ctx;
@@ -1657,6 +1667,8 @@ mono_get_method_constrained (MonoImage *image, guint32 token, MonoClass *constra
                        ctx.class_inst = method_context->class_inst;
                
                        sig = inflate_generic_signature (method->klass->image, sig, &ctx);
+                       if (sig == NULL)
+                               return NULL;
                }
        }
 
@@ -1729,14 +1741,22 @@ mono_method_get_param_names (MonoMethod *method, const char **names)
        MonoClass *klass;
        MonoTableInfo *methodt;
        MonoTableInfo *paramt;
+       MonoMethodSignature *signature;
        guint32 idx;
 
        if (method->is_inflated)
                method = ((MonoMethodInflated *) method)->declaring;
 
-       if (!mono_method_signature (method)->param_count)
+       signature = mono_method_signature (method);
+       /*FIXME this check is somewhat redundant since the caller usally will have to get the signature to figure out the
+         number of arguments and allocate a properly sized array. */
+       if (signature == NULL)
+               return;
+
+       if (!signature->param_count)
                return;
-       for (i = 0; i < mono_method_signature (method)->param_count; ++i)
+
+       for (i = 0; i < signature->param_count; ++i)
                names [i] = "";
 
        klass = method->klass;
@@ -1772,10 +1792,9 @@ mono_method_get_param_names (MonoMethod *method, const char **names)
                        lastp = paramt->rows + 1;
                for (i = param_index; i < lastp; ++i) {
                        mono_metadata_decode_row (paramt, i -1, cols, MONO_PARAM_SIZE);
-                       if (cols [MONO_PARAM_SEQUENCE]) /* skip return param spec */
+                       if (cols [MONO_PARAM_SEQUENCE] && cols [MONO_PARAM_SEQUENCE] <= signature->param_count) /* skip return param spec and bounds check*/
                                names [cols [MONO_PARAM_SEQUENCE] - 1] = mono_metadata_string_heap (klass->image, cols [MONO_PARAM_NAME]);
                }
-               return;
        }
 }
 
@@ -1814,9 +1833,13 @@ mono_method_get_marshal_info (MonoMethod *method, MonoMarshalSpec **mspecs)
        MonoClass *klass = method->klass;
        MonoTableInfo *methodt;
        MonoTableInfo *paramt;
+       MonoMethodSignature *signature;
        guint32 idx;
 
-       for (i = 0; i < mono_method_signature (method)->param_count + 1; ++i)
+       signature = mono_method_signature (method);
+       g_assert (signature); /*FIXME there is no way to signal error from this function*/
+
+       for (i = 0; i < signature->param_count + 1; ++i)
                mspecs [i] = NULL;
 
        if (method->klass->image->dynamic) {
@@ -1825,7 +1848,7 @@ mono_method_get_marshal_info (MonoMethod *method, MonoMarshalSpec **mspecs)
                                ((MonoDynamicImage*)method->klass->image)->method_aux_hash, method);
                if (method_aux && method_aux->param_marshall) {
                        MonoMarshalSpec **dyn_specs = method_aux->param_marshall;
-                       for (i = 0; i < mono_method_signature (method)->param_count + 1; ++i)
+                       for (i = 0; i < signature->param_count + 1; ++i)
                                if (dyn_specs [i]) {
                                        mspecs [i] = g_new0 (MonoMarshalSpec, 1);
                                        memcpy (mspecs [i], dyn_specs [i], sizeof (MonoMarshalSpec));
@@ -1851,7 +1874,7 @@ mono_method_get_marshal_info (MonoMethod *method, MonoMarshalSpec **mspecs)
                for (i = param_index; i < lastp; ++i) {
                        mono_metadata_decode_row (paramt, i -1, cols, MONO_PARAM_SIZE);
 
-                       if (cols [MONO_PARAM_FLAGS] & PARAM_ATTRIBUTE_HAS_FIELD_MARSHAL) {
+                       if (cols [MONO_PARAM_FLAGS] & PARAM_ATTRIBUTE_HAS_FIELD_MARSHAL && cols [MONO_PARAM_SEQUENCE] <= signature->param_count) {
                                const char *tp;
                                tp = mono_metadata_get_marshal_info (klass->image, i - 1, FALSE);
                                g_assert (tp);
@@ -2076,14 +2099,19 @@ mono_method_signature (MonoMethod *m)
 
        /* Verify metadata consistency */
        if (signature->generic_param_count) {
-               if (!container || !container->is_method)
-                       g_error ("Signature claims method has generic parameters, but generic_params table says it doesn't");
-               if (container->type_argc != signature->generic_param_count)
-                       g_error ("Inconsistent generic parameter count.  Signature says %d, generic_params table says %d",
-                                signature->generic_param_count, container->type_argc);
-       } else if (container && container->is_method && container->type_argc)
-               g_error ("generic_params table claims method has generic parameters, but signature says it doesn't");
-
+               if (!container || !container->is_method) {
+                       g_warning ("Signature claims method has generic parameters, but generic_params table says it doesn't for method 0x%08x from image %s", idx, img->name);
+                       return NULL;
+               }
+               if (container->type_argc != signature->generic_param_count) {
+                       g_warning ("Inconsistent generic parameter count.  Signature says %d, generic_params table says %dfor method 0x%08x from image %s",
+                                signature->generic_param_count, container->type_argc, idx, img->name);
+                       return NULL;
+               }
+       } else if (container && container->is_method && container->type_argc) {
+               g_warning ("generic_params table claims method has generic parameters, but signature says it doesn't for method 0x%08x from image %s", idx, img->name);
+               return NULL;
+       }
        if (m->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL)
                signature->pinvoke = 1;
        else if (m->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) {
@@ -2111,8 +2139,8 @@ mono_method_signature (MonoMethod *m)
                case PINVOKE_ATTRIBUTE_CALL_CONV_GENERIC:
                case PINVOKE_ATTRIBUTE_CALL_CONV_GENERICINST:
                default:
-                       g_warning ("unsupported calling convention : 0x%04x", piinfo->piflags);
-                       g_assert_not_reached ();
+                       g_warning ("unsupported calling convention : 0x%04x for method 0x%08x from image %s", piinfo->piflags, idx, img->name);
+                       return NULL;
                }
                signature->call_convention = conv;
        }
index d0b9341e81f38cdb07d6f6424964236cdedbd524..9d9341db7b2938c11f53b655bf1c430fad4cfd72 100644 (file)
@@ -170,7 +170,7 @@ signature_dup (MonoImage *image, MonoMethodSignature *sig)
        int sigsize;
 
        res = mono_metadata_signature_alloc (image, sig->param_count);
-       sigsize = sizeof (MonoMethodSignature) + ((sig->param_count - MONO_ZERO_LEN_ARRAY) * sizeof (MonoType *));
+       sigsize = MONO_SIZEOF_METHOD_SIGNATURE + sig->param_count * sizeof (MonoType *);
        memcpy (res, sig, sigsize);
 
        return res;
@@ -1696,7 +1696,7 @@ emit_object_to_ptr_conv (MonoMethodBuilder *mb, MonoType *type, MonoMarshalConv
        default: {
                char *msg = g_strdup_printf ("marshalling conversion %d not implemented", conv);
                MonoException *exc = mono_get_exception_not_implemented (msg);
-               g_warning (msg);
+               g_warning ("%s", msg);
                g_free (msg);
                mono_raise_exception (exc);
        }
@@ -3829,7 +3829,7 @@ signature_dup_add_this (MonoMethodSignature *sig, MonoClass *klass)
        int i;
 
        res = mono_metadata_signature_alloc (klass->image, sig->param_count + 1);
-       memcpy (res, sig, sizeof (MonoMethodSignature));
+       memcpy (res, sig, MONO_SIZEOF_METHOD_SIGNATURE);
        res->param_count = sig->param_count + 1;
        res->hasthis = FALSE;
        for (i = sig->param_count - 1; i >= 0; i --)
@@ -5625,7 +5625,7 @@ emit_marshal_string (EmitMarshalContext *m, int argnum, MonoType *t,
                if (conv == -1) {
                        char *msg = g_strdup_printf ("string marshalling conversion %d not implemented", encoding);
                        MonoException *exc = mono_get_exception_not_implemented (msg);
-                       g_warning (msg);
+                       g_warning ("%s", msg);
                        g_free (msg);
                        mono_raise_exception (exc);
                }
@@ -6002,7 +6002,7 @@ emit_marshal_object (EmitMarshalContext *m, int argnum, MonoType *t,
                        else {
                                char *msg = g_strdup_printf ("stringbuilder marshalling conversion %d not implemented", encoding);
                                MonoException *exc = mono_get_exception_not_implemented (msg);
-                               g_warning (msg);
+                               g_warning ("%s", msg);
                                g_free (msg);
                                mono_raise_exception (exc);
                        }
@@ -6582,7 +6582,7 @@ emit_marshal_array (EmitMarshalContext *m, int argnum, MonoType *t,
                                if (conv == -1) {
                                        char *msg = g_strdup_printf ("string/stringbuilder marshalling conversion %d not implemented", encoding);
                                        MonoException *exc = mono_get_exception_not_implemented (msg);
-                                       g_warning (msg);
+                                       g_warning ("%s", msg);
                                        g_free (msg);
                                        mono_raise_exception (exc);
                                }
@@ -10003,7 +10003,7 @@ mono_marshal_load_type_info (MonoClass* klass)
        layout = klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK;
 
        /* The mempool is protected by the loader lock */
-       info = mono_image_alloc0 (klass->image, sizeof (MonoMarshalType) + sizeof (MonoMarshalField) * count);
+       info = mono_image_alloc0 (klass->image, MONO_SIZEOF_MARSHAL_TYPE + sizeof (MonoMarshalField) * count);
        info->num_fields = count;
        
        /* Try to find a size for this type in metadata */
@@ -10558,7 +10558,7 @@ mono_marshal_get_thunk_invoke_wrapper (MonoMethod *method)
 
        /* dup & extend signature */
        csig = mono_metadata_signature_alloc (image, param_count);
-       sig_size = sizeof (MonoMethodSignature) + ((sig->param_count - MONO_ZERO_LEN_ARRAY) * sizeof (MonoType *));
+       sig_size = MONO_SIZEOF_METHOD_SIGNATURE + sig->param_count * sizeof (MonoType *);
        memcpy (csig, sig, sig_size);
        csig->param_count = param_count;
        csig->hasthis = 0;
index e27ffc770a1a527888ae2215d7dc4d2c3d9ea6ce..4213ce3aa53ce3477a177a9041724f92b4da1aef 100644 (file)
@@ -254,6 +254,8 @@ struct _MonoImage {
        /* interfaces IDs from this image */
        MonoBitSet *interface_bitset;
 
+       GSList *reflection_info_unregister_classes;
+
        /*
         * No other runtime locks must be taken while holding this lock.
         * It's meant to be used only to mutate and query structures part of this image.
@@ -373,6 +375,8 @@ struct _MonoMethodHeader {
        MonoType    *locals [MONO_ZERO_LEN_ARRAY];
 };
 
+#define MONO_SIZEOF_METHOD_HEADER (sizeof (struct _MonoMethodHeader) - MONO_ZERO_LEN_ARRAY * SIZEOF_VOID_P)
+
 /* for use with allocated memory blocks (assumes alignment is to 8 bytes) */
 guint mono_aligned_addr_hash (gconstpointer ptr) MONO_INTERNAL;
 
@@ -427,6 +431,7 @@ mono_metadata_interfaces_from_typedef_full  (MonoImage             *image,
                                                                                         guint32                table_index,
                                                                                         MonoClass           ***interfaces,
                                                                                         guint                 *count,
+                                                                                        gboolean               heap_alloc_result,
                                                                                         MonoGenericContext    *context) MONO_INTERNAL;
 
 MonoArrayType *
index 229b35273d136175834b48c689f771c768abf628..90625bcce9fbab3ce6fc59d4d27b252fb3118fac 100644 (file)
@@ -222,6 +222,7 @@ typedef struct {
        int valid;
        MonoImage *image;
        gboolean report_error;
+       gboolean report_warning;
        int stage;
 
        DataDirectory data_directories [16];
@@ -240,6 +241,13 @@ typedef struct {
                (__ctx)->errors = g_slist_prepend ((__ctx)->errors, vinfo);     \
        } while (0)
 
+#define ADD_WARNING(__ctx, __msg)      \
+       do {    \
+               if ((__ctx)->report_warning) \
+                       ADD_VERIFY_INFO(__ctx, __msg, MONO_VERIFY_WARNING, MONO_EXCEPTION_INVALID_PROGRAM); \
+               (__ctx)->valid = 0; \
+               return; \
+       } while (0)
 
 #define ADD_ERROR(__ctx, __msg)        \
        do {    \
@@ -2226,7 +2234,7 @@ verify_method_table (VerifyContext *ctx)
                }
 
                if (access == METHOD_ATTRIBUTE_COMPILER_CONTROLLED && (flags & (METHOD_ATTRIBUTE_RT_SPECIAL_NAME | METHOD_ATTRIBUTE_SPECIAL_NAME)))
-                       ADD_ERROR (ctx, g_strdup_printf ("Invalid method row %d is CompileControlled and SpecialName or RtSpecialName", i));
+                       ADD_WARNING (ctx, g_strdup_printf ("Invalid method row %d is CompileControlled and SpecialName or RtSpecialName", i));
 
                if ((flags & METHOD_ATTRIBUTE_RT_SPECIAL_NAME) && !(flags & METHOD_ATTRIBUTE_SPECIAL_NAME))
                        ADD_ERROR (ctx, g_strdup_printf ("Invalid method row %d is RTSpecialName but not SpecialName", i));
@@ -3292,6 +3300,7 @@ init_verify_context (VerifyContext *ctx, MonoImage *image, GSList **error_list)
        memset (ctx, 0, sizeof (VerifyContext));
        ctx->image = image;
        ctx->report_error = error_list != NULL;
+       ctx->report_warning = FALSE; //export this setting in the API
        ctx->valid = 1;
        ctx->size = image->raw_data_len;
        ctx->data = image->raw_data;
index 3ac1a5a54f6c6c719b818aab1a562d39f0b3d989..1927bcbc226de47d2c45495807e23e16019e2e07 100644 (file)
@@ -867,7 +867,7 @@ const char *
 mono_metadata_locate (MonoImage *meta, int table, int idx)
 {
        /* idx == 0 refers always to NULL */
-       g_return_val_if_fail (idx > 0 && idx <= meta->tables [table].rows, "");
+       g_return_val_if_fail (idx > 0 && idx <= meta->tables [table].rows, ""); /*FIXME shouldn't we return NULL here?*/
           
        return meta->tables [table].base + (meta->tables [table].row_size * (idx - 1));
 }
@@ -924,7 +924,7 @@ mono_metadata_user_string (MonoImage *meta, guint32 index)
 const char *
 mono_metadata_blob_heap (MonoImage *meta, guint32 index)
 {
-       g_return_val_if_fail (index < meta->heap_blob.size, "");
+       g_return_val_if_fail (index < meta->heap_blob.size, "");/*FIXME shouldn't we return NULL and check for index == 0?*/
        return meta->heap_blob.data + index;
 }
 
@@ -1282,13 +1282,13 @@ mono_metadata_parse_array_full (MonoImage *m, MonoGenericContainer *container,
 
        array->numsizes = mono_metadata_decode_value (ptr, &ptr);
        if (array->numsizes)
-               array->sizes = g_new0 (int, array->numsizes);
+               array->sizes = mono_image_alloc0 (m, sizeof (int) * array->numsizes);
        for (i = 0; i < array->numsizes; ++i)
                array->sizes [i] = mono_metadata_decode_value (ptr, &ptr);
 
        array->numlobounds = mono_metadata_decode_value (ptr, &ptr);
        if (array->numlobounds)
-               array->lobounds = g_new0 (int, array->numlobounds);
+               array->lobounds = mono_image_alloc0 (m, sizeof (int) * array->numlobounds);
        for (i = 0; i < array->numlobounds; ++i)
                array->lobounds [i] = mono_metadata_decode_signed_value (ptr, &ptr);
 
@@ -1591,13 +1591,13 @@ mono_metadata_parse_type_full (MonoImage *m, MonoGenericContainer *container, Mo
        }
 
        if (count) {
-               type = mono_image_alloc0 (m, sizeof (MonoType) + ((gint32)count - MONO_ZERO_LEN_ARRAY) * sizeof (MonoCustomMod));
+               type = mono_image_alloc0 (m, MONO_SIZEOF_TYPE + ((gint32)count) * sizeof (MonoCustomMod));
                type->num_mods = count;
                if (count > 64)
                        g_warning ("got more than 64 modifiers in type");
        } else {
                type = &stype;
-               memset (type, 0, sizeof (MonoType));
+               memset (type, 0, MONO_SIZEOF_TYPE);
        }
 
        /* Parse pinned, byref and custom modifiers */
@@ -1670,8 +1670,8 @@ mono_metadata_parse_type_full (MonoImage *m, MonoGenericContainer *container, Mo
        /* printf ("%x %x %c %s\n", type->attrs, type->num_mods, type->pinned ? 'p' : ' ', mono_type_full_name (type)); */
        
        if (type == &stype) {
-               type = mono_image_alloc (m, sizeof (MonoType));
-               memcpy (type, &stype, sizeof (MonoType));
+               type = mono_image_alloc (m, MONO_SIZEOF_TYPE);
+               memcpy (type, &stype, MONO_SIZEOF_TYPE);
        }
        return type;
 }
@@ -1785,7 +1785,7 @@ mono_metadata_signature_alloc (MonoImage *m, guint32 nparams)
 {
        MonoMethodSignature *sig;
 
-       sig = mono_image_alloc0 (m, sizeof (MonoMethodSignature) + ((gint32)nparams - MONO_ZERO_LEN_ARRAY) * sizeof (MonoType*));
+       sig = mono_image_alloc0 (m, MONO_SIZEOF_METHOD_SIGNATURE + ((gint32)nparams) * sizeof (MonoType*));
        sig->param_count = nparams;
        sig->sentinelpos = -1;
 
@@ -1797,7 +1797,7 @@ mono_metadata_signature_dup_internal (MonoImage *image, MonoMemPool *mp, MonoMet
 {
        int sigsize;
        MonoMethodSignature *ret;
-       sigsize = sizeof (MonoMethodSignature) + (sig->param_count - MONO_ZERO_LEN_ARRAY) * sizeof (MonoType *);
+       sigsize = MONO_SIZEOF_METHOD_SIGNATURE + sig->param_count * sizeof (MonoType *);
 
        if (image) {
                ret = mono_image_alloc (image, sigsize);
@@ -1846,7 +1846,7 @@ mono_metadata_signature_dup (MonoMethodSignature *sig)
 guint32
 mono_metadata_signature_size (MonoMethodSignature *sig)
 {
-       return sizeof (MonoMethodSignature) + (sig->param_count - MONO_ZERO_LEN_ARRAY) * sizeof (MonoType *);
+       return MONO_SIZEOF_METHOD_SIGNATURE + sig->param_count * sizeof (MonoType *);
 }
 
 /*
@@ -1906,10 +1906,16 @@ mono_metadata_parse_method_signature_full (MonoImage *m, MonoGenericContainer *c
 
        for (i = 0; i < method->param_count; ++i) {
                if (*ptr == MONO_TYPE_SENTINEL) {
-                       if (method->call_convention != MONO_CALL_VARARG || def)
-                               g_error ("found sentinel for methoddef or no vararg method");
-                       if (method->sentinelpos >= 0)
-                               g_error ("found sentinel twice in the same signature");
+                       if (method->call_convention != MONO_CALL_VARARG || def) {
+                               g_warning ("found sentinel for methoddef or no vararg method 0x%08x on image %s", def, m->name);
+                               g_free (pattrs);
+                               return NULL;
+                       }
+                       if (method->sentinelpos >= 0) {
+                               g_warning ("found sentinel twice in the same signature for method 0x%08x on image %s", def, m->name);
+                               g_free (pattrs);
+                               return NULL;
+                       }
                        method->sentinelpos = i;
                        ptr++;
                }
@@ -2394,7 +2400,7 @@ mono_metadata_get_generic_inst (int type_argc, MonoType **type_argv)
        MonoGenericInst *ginst;
        gboolean is_open;
        int i;
-       int size = sizeof (MonoGenericInst) + (type_argc - MONO_ZERO_LEN_ARRAY) * sizeof (MonoType *);
+       int size = MONO_SIZEOF_GENERIC_INST + type_argc * sizeof (MonoType *);
 
        for (i = 0; i < type_argc; ++i)
                if (mono_class_is_open_constructed_type (type_argv [i]))
@@ -2729,6 +2735,8 @@ do_mono_metadata_parse_type (MonoType *type, MonoImage *m, MonoGenericContainer
                if (!etype)
                        return FALSE;
                type->data.klass = mono_class_from_mono_type (etype);
+               if (!type->data.klass)
+                       return FALSE;
                break;
        }
        case MONO_TYPE_PTR:
@@ -2738,21 +2746,28 @@ do_mono_metadata_parse_type (MonoType *type, MonoImage *m, MonoGenericContainer
                break;
        case MONO_TYPE_FNPTR:
                type->data.method = mono_metadata_parse_method_signature_full (m, container, 0, ptr, &ptr);
+               if (!type->data.method)
+                       return FALSE;
                break;
        case MONO_TYPE_ARRAY:
                type->data.array = mono_metadata_parse_array_full (m, container, ptr, &ptr);
+               if (!type->data.array)
+                       return FALSE;
                break;
        case MONO_TYPE_MVAR:
                if (container && !container->is_method)
                        return FALSE;
        case MONO_TYPE_VAR:
                type->data.generic_param = mono_metadata_parse_generic_param (m, container, type->type, ptr, &ptr);
+               if (!type->data.generic_param)
+                       return FALSE;
                break;
        case MONO_TYPE_GENERICINST:
                ok = do_mono_metadata_parse_generic_class (type, m, container, ptr, &ptr);
                break;
        default:
-               g_error ("type 0x%02x not handled in do_mono_metadata_parse_type", type->type);
+               g_warning ("type 0x%02x not handled in do_mono_metadata_parse_type on image %s", type->type, m->name);
+               return FALSE;
        }
        
        if (rptr)
@@ -2927,23 +2942,10 @@ mono_metadata_parse_mh_full (MonoImage *m, MonoGenericContainer *container, cons
 
        switch (format) {
        case METHOD_HEADER_TINY_FORMAT:
-               mh = mono_image_alloc0 (m, sizeof (MonoMethodHeader));
-               ptr++;
-               mh->max_stack = 8;
-               local_var_sig_tok = 0;
-               mh->code_size = flags >> 2;
-               mh->code = (unsigned char*)ptr;
-               return mh;
-       case METHOD_HEADER_TINY_FORMAT1:
-               mh = mono_image_alloc0 (m, sizeof (MonoMethodHeader));
+               mh = mono_image_alloc0 (m, MONO_SIZEOF_METHOD_HEADER);
                ptr++;
                mh->max_stack = 8;
                local_var_sig_tok = 0;
-
-               /*
-                * The spec claims 3 bits, but the Beta2 is
-                * incorrect
-                */
                mh->code_size = flags >> 2;
                mh->code = (unsigned char*)ptr;
                return mh;
@@ -2994,7 +2996,7 @@ mono_metadata_parse_mh_full (MonoImage *m, MonoGenericContainer *container, cons
                        g_warning ("wrong signature for locals blob");
                locals_ptr++;
                len = mono_metadata_decode_value (locals_ptr, &locals_ptr);
-               mh = mono_image_alloc0 (m, sizeof (MonoMethodHeader) + (len - MONO_ZERO_LEN_ARRAY) * sizeof (MonoType*));
+               mh = mono_image_alloc0 (m, MONO_SIZEOF_METHOD_HEADER + len * sizeof (MonoType*));
                mh->num_locals = len;
                for (i = 0; i < len; ++i) {
                        mh->locals [i] = mono_metadata_parse_type_full (
@@ -3004,7 +3006,7 @@ mono_metadata_parse_mh_full (MonoImage *m, MonoGenericContainer *container, cons
                        }
                }
        } else {
-               mh = mono_image_alloc0 (m, sizeof (MonoMethodHeader));
+               mh = mono_image_alloc0 (m, MONO_SIZEOF_METHOD_HEADER);
        }
        mh->code = code;
        mh->code_size = code_size;
@@ -3416,16 +3418,20 @@ mono_metadata_typedef_from_method (MonoImage *meta, guint32 index)
  * mono_metadata_interfaces_from_typedef_full:
  * @meta: metadata context
  * @index: typedef token
+ * @interfaces: Out parameter used to store the interface array
+ * @count: Out parameter used to store the number of interfaces
+ * @heap_alloc_result: if TRUE the result array will be g_malloc'd
+ * @context: The generic context
  * 
  * The array of interfaces that the @index typedef token implements is returned in
- * @interfaces. The number of elemnts in the array is returned in @count.
+ * @interfaces. The number of elements in the array is returned in @count. 
  *
  * LOCKING: Assumes the loader lock is held.
  *
  * Returns: TRUE on success, FALSE on failure.
  */
 gboolean
-mono_metadata_interfaces_from_typedef_full (MonoImage *meta, guint32 index, MonoClass ***interfaces, guint *count, MonoGenericContext *context)
+mono_metadata_interfaces_from_typedef_full (MonoImage *meta, guint32 index, MonoClass ***interfaces, guint *count, gboolean heap_alloc_result, MonoGenericContext *context)
 {
        MonoTableInfo *tdef = &meta->tables [MONO_TABLE_INTERFACEIMPL];
        locator_t loc;
@@ -3464,7 +3470,10 @@ mono_metadata_interfaces_from_typedef_full (MonoImage *meta, guint32 index, Mono
                ++pos;
        }
 
-       result = mono_image_alloc0 (meta, sizeof (MonoClass*) * (pos - start));
+       if (heap_alloc_result)
+               result = g_new0 (MonoClass*, pos - start);
+       else
+               result = mono_image_alloc0 (meta, sizeof (MonoClass*) * (pos - start));
 
        pos = start;
        while (pos < tdef->rows) {
@@ -3485,6 +3494,20 @@ mono_metadata_interfaces_from_typedef_full (MonoImage *meta, guint32 index, Mono
        return TRUE;
 }
 
+/*
+ * @meta: metadata context
+ * @index: typedef token
+ * @count: Out parameter used to store the number of interfaces
+ * 
+ * The array of interfaces that the @index typedef token implements is returned in
+ * @interfaces. The number of elements in the array is returned in @count. The returned
+ * array is g_malloc'd and the caller must free it.
+ *
+ * LOCKING: Acquires the loader lock .
+ *
+ * Returns: the interface array on success, NULL on failure.
+ */
+
 MonoClass**
 mono_metadata_interfaces_from_typedef (MonoImage *meta, guint32 index, guint *count)
 {
@@ -3492,7 +3515,7 @@ mono_metadata_interfaces_from_typedef (MonoImage *meta, guint32 index, guint *co
        gboolean rv;
 
        mono_loader_lock ();
-       rv = mono_metadata_interfaces_from_typedef_full (meta, index, &interfaces, count, NULL);
+       rv = mono_metadata_interfaces_from_typedef_full (meta, index, &interfaces, count, TRUE, NULL);
        mono_loader_unlock ();
        if (rv)
                return interfaces;
@@ -4225,9 +4248,9 @@ MonoType *
 mono_metadata_type_dup (MonoImage *image, const MonoType *o)
 {
        MonoType *r = NULL;
-       int sizeof_o = sizeof (MonoType);
+       int sizeof_o = MONO_SIZEOF_TYPE;
        if (o->num_mods)
-               sizeof_o += (o->num_mods - MONO_ZERO_LEN_ARRAY) * sizeof (MonoCustomMod);
+               sizeof_o += o->num_mods  * sizeof (MonoCustomMod);
 
        r = image ? mono_image_alloc0 (image, sizeof_o) : g_malloc (sizeof_o);
 
@@ -4653,7 +4676,7 @@ mono_type_create_from_typespec (MonoImage *image, guint32 type_spec)
 
        len = mono_metadata_decode_value (ptr, &ptr);
 
-       type = mono_image_alloc0 (image, sizeof (MonoType));
+       type = mono_image_alloc0 (image, MONO_SIZEOF_TYPE);
 
        if (*ptr == MONO_TYPE_BYREF) {
                type->byref = 1;
@@ -5305,43 +5328,95 @@ mono_get_shared_generic_inst (MonoGenericContainer *container)
        return nginst;
 }
 
+/**
+ * mono_type_is_byref:
+ * @type: the MonoType operated on
+ *
+ * Returns: #TRUE if @type represents a type passed by reference,
+ * #FALSE otherwise.
+ */
 gboolean
 mono_type_is_byref (MonoType *type)
 {
        return type->byref;
 }
 
+/**
+ * mono_type_get_type:
+ * @type: the MonoType operated on
+ *
+ * Returns: the IL type value for @type. This is one of the MonoTypeEnum
+ * enum members like MONO_TYPE_I4 or MONO_TYPE_STRING.
+ */
 int
 mono_type_get_type (MonoType *type)
 {
        return type->type;
 }
 
-/* For MONO_TYPE_FNPTR */
+/**
+ * mono_type_get_signature:
+ * @type: the MonoType operated on
+ *
+ * It is only valid to call this function if @type is a MONO_TYPE_FNPTR.
+ *
+ * Returns: the MonoMethodSignature pointer that describes the signature
+ * of the function pointer @type represents.
+ */
 MonoMethodSignature*
 mono_type_get_signature (MonoType *type)
 {
+       g_assert (type->type == MONO_TYPE_FNPTR);
        return type->data.method;
 }
 
-/* For MONO_TYPE_CLASS, VALUETYPE */
+/**
+ * mono_type_get_class:
+ * @type: the MonoType operated on
+ *
+ * It is only valid to call this function if @type is a MONO_TYPE_CLASS or a
+ * MONO_TYPE_VALUETYPE. For more general functionality, use mono_class_from_mono_type (),
+ * instead
+ *
+ * Returns: the MonoClass pointer that describes the class that @type represents.
+ */
 MonoClass*
 mono_type_get_class (MonoType *type)
 {
+       /* FIXME: review the runtime users before adding the assert here */
        return type->data.klass;
 }
 
-/* For MONO_TYPE_ARRAY */
+/**
+ * mono_type_get_array_type:
+ * @type: the MonoType operated on
+ *
+ * It is only valid to call this function if @type is a MONO_TYPE_ARRAY.
+ *
+ * Returns: a MonoArrayType struct describing the array type that @type
+ * represents. The info includes details such as rank, array element type
+ * and the sizes and bounds of multidimensional arrays.
+ */
 MonoArrayType*
 mono_type_get_array_type (MonoType *type)
 {
        return type->data.array;
 }
 
-/* For MONO_TYPE_PTR */
+/**
+ * mono_type_get_ptr_type:
+ * @type: the MonoType operated on
+ *
+ * It is only valid to call this function if @type is a MONO_TYPE_PTR.
+ * instead
+ *
+ * Returns: the MonoType pointer that describes the type that @type
+ * represents a pointer to.
+ */
 MonoType*
 mono_type_get_ptr_type (MonoType *type)
 {
+       g_assert (type->type == MONO_TYPE_PTR);
        return type->data.type;
 }
 
index f86f80ca4aad835e2b78ee8fcd7330817e4176f1..6c01ca76822318ffee6c2ccf4cdbd583b1d8f2e8 100644 (file)
 
 G_BEGIN_DECLS
 
+/*
+ * When embedding, you have to define MONO_ZERO_LEN_ARRAY before including any
+ * other Mono header file if you use a different compiler from the one used to
+ * build Mono.
+ */
+#ifndef MONO_ZERO_LEN_ARRAY
 #ifdef __GNUC__
 #define MONO_ZERO_LEN_ARRAY 0
 #else
 #define MONO_ZERO_LEN_ARRAY 1
 #endif
+#endif
 
 #define MONO_TYPE_ISSTRUCT(t) (!(t)->byref && (((t)->type == MONO_TYPE_VALUETYPE && \
        !(t)->data.klass->enumtype) || ((t)->type == MONO_TYPE_TYPEDBYREF) || \
@@ -342,6 +349,8 @@ struct _MonoType {
        MonoCustomMod modifiers [MONO_ZERO_LEN_ARRAY]; /* this may grow */
 };
 
+#define MONO_SIZEOF_TYPE (offsetof (struct _MonoType, modifiers))
+
 /*
  * This structure is an internal runtime detail: use the mono_signature_*
  * accessors below, because it will go away from the public header.
@@ -361,6 +370,8 @@ struct _MonoMethodSignature {
        MonoType     *params [MONO_ZERO_LEN_ARRAY];
 };
 
+#define MONO_SIZEOF_METHOD_SIGNATURE (sizeof (struct _MonoMethodSignature) - MONO_ZERO_LEN_ARRAY * SIZEOF_VOID_P)
+
 typedef struct _MonoMethodHeader MonoMethodHeader;
 
 typedef enum {
index 102422006765095f05857fcec2b5f48fe8e6454e..74b42a204e0695da6718cc55b505a8e26c8e676d 100644 (file)
@@ -147,7 +147,7 @@ mono_mb_create_method (MonoMethodBuilder *mb, MonoMethodSignature *signature, in
                method->dynamic = TRUE;
 
                ((MonoMethodNormal *)method)->header = header = (MonoMethodHeader *) 
-                       g_malloc0 (sizeof (MonoMethodHeader) + mb->locals * sizeof (MonoType *));
+                       g_malloc0 (MONO_SIZEOF_METHOD_HEADER + mb->locals * sizeof (MonoType *));
 
                header->code = mb->code;
 
@@ -166,7 +166,7 @@ mono_mb_create_method (MonoMethodBuilder *mb, MonoMethodSignature *signature, in
                        method->name = mono_image_strdup (image, mb->name);
 
                ((MonoMethodNormal *)method)->header = header = (MonoMethodHeader *) 
-                       mono_image_alloc0 (image, sizeof (MonoMethodHeader) + mb->locals * sizeof (MonoType *));
+                       mono_image_alloc0 (image, MONO_SIZEOF_METHOD_HEADER + mb->locals * sizeof (MonoType *));
 
                header->code = mono_image_alloc (image, mb->pos);
                memcpy ((char*)header->code, mb->code, mb->pos);
index 18c31b20e022e176d04dc59cedcd0b5385c7ec97..22b0a228f8ffb007eb31e895b47b4d76b068eed4 100644 (file)
@@ -1750,7 +1750,7 @@ mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *class)
        }
 
        if (ARCH_USE_IMT) {
-               vtable_size = sizeof (MonoVTable) + class->vtable_size * sizeof (gpointer);
+               vtable_size = MONO_SIZEOF_VTABLE + class->vtable_size * sizeof (gpointer);
                if (class->interface_offsets_count) {
                        imt_table_bytes = sizeof (gpointer) * (MONO_IMT_SIZE);
                        vtable_size += sizeof (gpointer) * (MONO_IMT_SIZE);
@@ -1759,7 +1759,7 @@ mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *class)
                }
        } else {
                vtable_size = sizeof (gpointer) * (class->max_interface_id + 1) +
-                       sizeof (MonoVTable) + class->vtable_size * sizeof (gpointer);
+                       MONO_SIZEOF_VTABLE + class->vtable_size * sizeof (gpointer);
        }
 
        mono_stats.used_class_count++;
@@ -1901,7 +1901,7 @@ mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *class)
                /* this is a bounded memory retention issue: may want to 
                 * handle it differently when we'll have a rcu-like system.
                 */
-               runtime_info = mono_image_alloc0 (class->image, sizeof (MonoClassRuntimeInfo) + new_size * sizeof (gpointer));
+               runtime_info = mono_image_alloc0 (class->image, MONO_SIZEOF_CLASS_RUNTIME_INFO + new_size * sizeof (gpointer));
                runtime_info->max_domain = new_size - 1;
                /* copy the stuff from the older info */
                if (old_info) {
@@ -2024,10 +2024,10 @@ mono_class_proxy_vtable (MonoDomain *domain, MonoRemoteClass *remote_class, Mono
                mono_stats.imt_number_of_tables++;
                mono_stats.imt_tables_size += (sizeof (gpointer) * MONO_IMT_SIZE);
                vtsize = sizeof (gpointer) * (MONO_IMT_SIZE) +
-                       sizeof (MonoVTable) + class->vtable_size * sizeof (gpointer);
+                       MONO_SIZEOF_VTABLE + class->vtable_size * sizeof (gpointer);
        } else {
                vtsize = sizeof (gpointer) * (max_interface_id + 1) +
-                       sizeof (MonoVTable) + class->vtable_size * sizeof (gpointer);
+                       MONO_SIZEOF_VTABLE + class->vtable_size * sizeof (gpointer);
        }
 
        mono_stats.class_vtable_size += vtsize + extra_interface_vtsize;
@@ -2037,7 +2037,7 @@ mono_class_proxy_vtable (MonoDomain *domain, MonoRemoteClass *remote_class, Mono
                pvt = (MonoVTable*) (interface_offsets + MONO_IMT_SIZE);
        else
                pvt = (MonoVTable*) (interface_offsets + max_interface_id + 1);
-       memcpy (pvt, vt, sizeof (MonoVTable) + class->vtable_size * sizeof (gpointer));
+       memcpy (pvt, vt, MONO_SIZEOF_VTABLE + class->vtable_size * sizeof (gpointer));
 
        pvt->klass = mono_defaults.transparent_proxy_class;
        /* we need to keep the GC descriptor for a transparent proxy or we confuse the precise GC */
@@ -2257,12 +2257,12 @@ mono_remote_class (MonoDomain *domain, MonoString *class_name, MonoClass *proxy_
        key = mp_key;
 
        if (proxy_class->flags & TYPE_ATTRIBUTE_INTERFACE) {
-               rc = mono_domain_alloc (domain, sizeof(MonoRemoteClass) + sizeof(MonoClass*));
+               rc = mono_domain_alloc (domain, MONO_SIZEOF_REMOTE_CLASS + sizeof(MonoClass*));
                rc->interface_count = 1;
                rc->interfaces [0] = proxy_class;
                rc->proxy_class = mono_defaults.marshalbyrefobject_class;
        } else {
-               rc = mono_domain_alloc (domain, sizeof(MonoRemoteClass));
+               rc = mono_domain_alloc (domain, MONO_SIZEOF_REMOTE_CLASS);
                rc->interface_count = 0;
                rc->proxy_class = proxy_class;
        }
@@ -2301,7 +2301,7 @@ clone_remote_class (MonoDomain *domain, MonoRemoteClass* remote_class, MonoClass
 
        if (extra_class->flags & TYPE_ATTRIBUTE_INTERFACE) {
                int i,j;
-               rc = mono_domain_alloc (domain, sizeof(MonoRemoteClass) + sizeof(MonoClass*) * (remote_class->interface_count + 1));
+               rc = mono_domain_alloc (domain, MONO_SIZEOF_REMOTE_CLASS + sizeof(MonoClass*) * (remote_class->interface_count + 1));
                rc->proxy_class = remote_class->proxy_class;
                rc->interface_count = remote_class->interface_count + 1;
                
@@ -2316,7 +2316,7 @@ clone_remote_class (MonoDomain *domain, MonoRemoteClass* remote_class, MonoClass
                        rc->interfaces [j] = extra_class;
        } else {
                // Replace the old class. The interface array is the same
-               rc = mono_domain_alloc (domain, sizeof(MonoRemoteClass) + sizeof(MonoClass*) * remote_class->interface_count);
+               rc = mono_domain_alloc (domain, MONO_SIZEOF_REMOTE_CLASS + sizeof(MonoClass*) * remote_class->interface_count);
                rc->proxy_class = extra_class;
                rc->interface_count = remote_class->interface_count;
                if (rc->interface_count > 0)
index b6087e7c3678bc3bd40b2317957fb6783030dec9..a184033312ad6cc95756523dc758a153a10ae946 100644 (file)
@@ -1650,7 +1650,7 @@ mono_profiler_load (const char *desc)
        }
 #endif
        {
-               MonoDl *pmodule;
+               MonoDl *pmodule = NULL;
                const char* col = strchr (desc, ':');
                char* libname;
                char* path;
index 6c40a9a58bc9b18dd47ac13bb1f532a1b2e9edb2..e472ed31d38c922267bcc6d1d4f094a04080fd2d 100644 (file)
@@ -1122,7 +1122,7 @@ lookup_custom_attr (MonoImage *image, gpointer member)
        if (!res)
                return NULL;
 
-       return g_memdup (res, sizeof (MonoCustomAttrInfo) + sizeof (MonoCustomAttrEntry) * (res->num_attrs - MONO_ZERO_LEN_ARRAY));
+       return g_memdup (res, MONO_SIZEOF_CUSTOM_ATTR_INFO + sizeof (MonoCustomAttrEntry) * res->num_attrs);
 }
 
 static gboolean
@@ -1162,7 +1162,7 @@ mono_custom_attrs_from_builders (MonoImage *alloc_img, MonoImage *image, MonoArr
        }
        count -= not_visible;
 
-       ainfo = image_g_malloc0 (alloc_img, sizeof (MonoCustomAttrInfo) + sizeof (MonoCustomAttrEntry) * (count - MONO_ZERO_LEN_ARRAY));
+       ainfo = image_g_malloc0 (alloc_img, MONO_SIZEOF_CUSTOM_ATTR_INFO + sizeof (MonoCustomAttrEntry) * count);
 
        ainfo->image = image;
        ainfo->num_attrs = count;
@@ -2959,9 +2959,9 @@ add_custom_modifiers (MonoDynamicImage *assembly, MonoType *type, MonoArray *mod
        if (count == 0)
                return mono_metadata_type_dup (NULL, type);
 
-       len = sizeof (MonoType) + ((gint32)count - MONO_ZERO_LEN_ARRAY) * sizeof (MonoCustomMod);
+       len = MONO_SIZEOF_TYPE + ((gint32)count) * sizeof (MonoCustomMod);
        t = g_malloc (len);
-       memcpy (t, type, sizeof (MonoType));
+       memcpy (t, type, MONO_SIZEOF_TYPE);
 
        t->num_mods = count;
        pos = 0;
@@ -3150,7 +3150,7 @@ mono_image_get_array_token (MonoDynamicImage *assembly, MonoReflectionArrayMetho
 
        name = mono_string_to_utf8 (m->name);
        nparams = mono_array_length (m->parameters);
-       sig = g_malloc0 (sizeof (MonoMethodSignature) + sizeof (MonoType*) * nparams);
+       sig = g_malloc0 (MONO_SIZEOF_METHOD_SIGNATURE + sizeof (MonoType*) * nparams);
        sig->hasthis = 1;
        sig->sentinelpos = -1;
        sig->call_convention = reflection_cc_to_file (m->call_conv);
@@ -6694,7 +6694,6 @@ mono_method_body_get_object (MonoDomain *domain, MonoMethod *method)
        format = flags & METHOD_HEADER_FORMAT_MASK;
        switch (format){
        case METHOD_HEADER_TINY_FORMAT:
-       case METHOD_HEADER_TINY_FORMAT1:
                local_var_sig_token = 0;
                break;
        case METHOD_HEADER_FAT_FORMAT:
@@ -6825,7 +6824,7 @@ get_default_param_value_blobs (MonoMethod *method, char **blobs, guint32 *types)
                mono_metadata_decode_row (paramt, i - 1, param_cols, MONO_PARAM_SIZE);
                paramseq = param_cols [MONO_PARAM_SEQUENCE];
 
-               if (!param_cols [MONO_PARAM_FLAGS] & PARAM_ATTRIBUTE_HAS_DEFAULT) 
+               if (!(param_cols [MONO_PARAM_FLAGS] & PARAM_ATTRIBUTE_HAS_DEFAULT))
                        continue;
 
                crow = mono_metadata_get_constant_index (image, MONO_TOKEN_PARAM_DEF | i, crow + 1);
@@ -8160,7 +8159,7 @@ mono_custom_attrs_from_index (MonoImage *image, guint32 idx)
        len = g_list_length (list);
        if (!len)
                return NULL;
-       ainfo = g_malloc0 (sizeof (MonoCustomAttrInfo) + sizeof (MonoCustomAttrEntry) * (len - MONO_ZERO_LEN_ARRAY));
+       ainfo = g_malloc0 (MONO_SIZEOF_CUSTOM_ATTR_INFO + sizeof (MonoCustomAttrEntry) * len);
        ainfo->num_attrs = len;
        ainfo->image = image;
        for (i = 0, tmp = list; i < len; ++i, tmp = tmp->next) {
@@ -8341,7 +8340,7 @@ mono_custom_attrs_from_param (MonoMethod *method, guint32 param)
 
                /* Need to copy since it will be freed later */
                ainfo = aux->param_cattr [param];
-               size = sizeof (MonoCustomAttrInfo) + sizeof (MonoCustomAttrEntry) * (ainfo->num_attrs - MONO_ZERO_LEN_ARRAY);
+               size = MONO_SIZEOF_CUSTOM_ATTR_INFO + sizeof (MonoCustomAttrEntry) * ainfo->num_attrs;
                res = g_malloc0 (size);
                memcpy (res, ainfo, size);
                return res;
@@ -8613,6 +8612,12 @@ is_sre_pointer (MonoClass *class)
        check_corlib_type_cached (class, "System.Reflection.Emit", "PointerType");
 }
 
+static gboolean
+is_sre_generic_instance (MonoClass *class)
+{
+       check_corlib_type_cached (class, "System.Reflection", "MonoGenericClass");
+}
+
 MonoType*
 mono_reflection_type_get_handle (MonoReflectionType* ref)
 {
@@ -8658,6 +8663,23 @@ mono_reflection_type_get_handle (MonoReflectionType* ref)
                res = &mono_ptr_class_get (base)->byval_arg;
                sre_pointer->type.type = res;
                return res;
+       } else if (is_sre_generic_instance (class)) {
+               MonoType *res, **types;
+               MonoReflectionGenericClass *gclass = (MonoReflectionGenericClass*)ref;
+               int i, count;
+
+               count = mono_array_length (gclass->type_arguments);
+               types = g_new0 (MonoType*, count);
+               for (i = 0; i < count; ++i) {
+                       MonoReflectionType *t = mono_array_get (gclass->type_arguments, gpointer, i);
+                       types [i] = mono_reflection_type_get_handle (t);
+               }
+
+               res = mono_reflection_bind_generic_parameters ((MonoReflectionType*)gclass->generic_type, count, types);
+               g_free (types);
+               g_assert (res);
+               gclass->type.type = res;
+               return res;
        }
 
        g_error ("Cannot handle corlib user type %s", mono_type_full_name (&mono_object_class(ref)->byval_arg));
@@ -8695,7 +8717,7 @@ parameters_to_signature (MonoImage *image, MonoArray *parameters) {
 
        count = parameters? mono_array_length (parameters): 0;
 
-       sig = image_g_malloc0 (image, sizeof (MonoMethodSignature) + sizeof (MonoType*) * count);
+       sig = image_g_malloc0 (image, MONO_SIZEOF_METHOD_SIGNATURE + sizeof (MonoType*) * count);
        sig->param_count = count;
        sig->sentinelpos = -1; /* FIXME */
        for (i = 0; i < count; ++i)
@@ -8875,27 +8897,12 @@ handle_enum:
        case MONO_TYPE_CLASS: {
                char *str;
                guint32 slen;
-               MonoClass *k;
                if (!arg) {
                        *p++ = 0xFF;
                        break;
                }
-               k = mono_object_class (arg);
-               if (!mono_object_isinst (arg, mono_defaults.monotype_class) &&
-                        (strcmp (k->name, "TypeBuilder") || strcmp (k->name_space, "System.Reflection.Emit"))) {
-                        MonoReflectionType* rt = mono_reflection_type_get_underlying_system_type ((MonoReflectionType*) arg);
-                        MonoClass *rtc;
-                        
-                        if (rt && (rtc = mono_object_class (rt)) &&
-                                   (mono_object_isinst ((MonoObject *) rt, mono_defaults.monotype_class) ||
-                                    !strcmp (rtc->name, "TypeBuilder") || !strcmp (rtc->name_space, "System.Reflection.Emit"))) {
-                                arg = (MonoObject *) rt;
-                                k = rtc;
-                        } else
-                                g_error ("Only System.Type allowed, not %s.%s", k->name_space, k->name);
-                }
 handle_type:
-               str = type_get_qualified_name (((MonoReflectionType*)arg)->type, NULL);
+               str = type_get_qualified_name (mono_reflection_type_get_handle ((MonoReflectionType*)arg), NULL);
                slen = strlen (str);
                if ((p-buffer) + 10 + slen >= *buflen) {
                        char *newbuf;
@@ -9584,8 +9591,7 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
                        }
                }
 
-               header = image_g_malloc0 (image, sizeof (MonoMethodHeader) + 
-                       (num_locals - MONO_ZERO_LEN_ARRAY) * sizeof (MonoType*));
+               header = image_g_malloc0 (image, MONO_SIZEOF_METHOD_HEADER + num_locals * sizeof (MonoType*));
                header->code_size = code_size;
                header->code = image_g_malloc (image, code_size);
                memcpy ((char*)header->code, code, code_size);
@@ -9598,7 +9604,7 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
                                mono_array_get (rmb->ilgen->locals, MonoReflectionLocalBuilder*, i);
 
                        header->locals [i] = image_g_new0 (image, MonoType, 1);
-                       memcpy (header->locals [i], mono_reflection_type_get_handle ((MonoReflectionType*)lb->type), sizeof (MonoType));
+                       memcpy (header->locals [i], mono_reflection_type_get_handle ((MonoReflectionType*)lb->type), MONO_SIZEOF_TYPE);
                }
 
                header->num_clauses = num_clauses;
@@ -10679,6 +10685,9 @@ mono_reflection_initialize_generic_parameter (MonoReflectionGenericParam *gparam
 
        MOVING_GC_REGISTER (&pklass->reflection_info);
        pklass->reflection_info = gparam; /* FIXME: GC pin gparam */
+       mono_image_lock (image);
+       image->reflection_info_unregister_classes = g_slist_prepend (image->reflection_info_unregister_classes, pklass);
+       mono_image_unlock (image);
 }
 
 MonoArray *
index 89b336088e45d437b3e28a9c781e08e9b651b932..801c6a07ab978355c54a2edd887294a7ed83e8a3 100644 (file)
@@ -29,6 +29,8 @@ typedef struct {
        MonoCustomAttrEntry attrs [MONO_ZERO_LEN_ARRAY];
 } MonoCustomAttrInfo;
 
+#define MONO_SIZEOF_CUSTOM_ATTR_INFO (offsetof (MonoCustomAttrInfo, attrs))
+
 /* 
  * Information which isn't in the MonoMethod structure is stored here for
  * dynamic methods.
index bb79bcb7abc3bed0222b72953518dfbd39a5ddf3..9366b5ba324e5ac4181aafa66eee4aca4595e9a6 100644 (file)
@@ -1276,14 +1276,25 @@ static mword obj_references_checked = 0;
  * This section of code deals with detecting the objects no longer in use
  * and reclaiming the memory.
  */
+
+#define COUNT_OBJECT_TYPES do {                                                \
+       switch (desc & 0x7) {                                           \
+       case DESC_TYPE_STRING: type_str++; break;                       \
+       case DESC_TYPE_RUN_LENGTH: type_rlen++; break;                  \
+       case DESC_TYPE_ARRAY: case DESC_TYPE_VECTOR: type_vector++; break; \
+       case DESC_TYPE_SMALL_BITMAP: type_bitmap++; break;              \
+       case DESC_TYPE_LARGE_BITMAP: type_lbit++; break;                \
+       case DESC_TYPE_COMPLEX: type_complex++; break;                  \
+       case DESC_TYPE_COMPLEX_ARR: type_complex++; break;              \
+       default: g_assert_not_reached ();                               \
+       }                                                               \
+       } while (0)
+
 static void __attribute__((noinline))
 scan_area (char *start, char *end)
 {
        GCVTable *vt;
-       size_t skip_size;
-       int type;
        int type_str = 0, type_rlen = 0, type_bitmap = 0, type_vector = 0, type_lbit = 0, type_complex = 0;
-       mword desc;
        new_obj_references = 0;
        obj_references_checked = 0;
        while (start < end) {
@@ -1297,64 +1308,9 @@ scan_area (char *start, char *end)
                        MonoObject *obj = (MonoObject*)start;
                        g_print ("found at %p (0x%zx): %s.%s\n", start, vt->desc, obj->vtable->klass->name_space, obj->vtable->klass->name);
                }
-               desc = vt->desc;
-               type = desc & 0x7;
-               if (type == DESC_TYPE_STRING) {
-                       STRING_SIZE (skip_size, start);
-                       start += skip_size;
-                       type_str++;
-                       continue;
-               } else if (type == DESC_TYPE_RUN_LENGTH) {
-                       OBJ_RUN_LEN_SIZE (skip_size, desc, start);
-                       g_assert (skip_size);
-                       OBJ_RUN_LEN_FOREACH_PTR (desc,start);
-                       start += skip_size;
-                       type_rlen++;
-                       continue;
-               } else if (type == DESC_TYPE_VECTOR) { // includes ARRAY, too
-                       skip_size = safe_object_get_size ((MonoObject*)start);
-                       skip_size += (ALLOC_ALIGN - 1);
-                       skip_size &= ~(ALLOC_ALIGN - 1);
-                       OBJ_VECTOR_FOREACH_PTR (vt, start);
-                       start += skip_size;
-                       type_vector++;
-                       continue;
-               } else if (type == DESC_TYPE_SMALL_BITMAP) {
-                       OBJ_BITMAP_SIZE (skip_size, desc, start);
-                       g_assert (skip_size);
-                       OBJ_BITMAP_FOREACH_PTR (desc,start);
-                       start += skip_size;
-                       type_bitmap++;
-                       continue;
-               } else if (type == DESC_TYPE_LARGE_BITMAP) {
-                       skip_size = safe_object_get_size ((MonoObject*)start);
-                       skip_size += (ALLOC_ALIGN - 1);
-                       skip_size &= ~(ALLOC_ALIGN - 1);
-                       OBJ_LARGE_BITMAP_FOREACH_PTR (vt,start);
-                       start += skip_size;
-                       type_lbit++;
-                       continue;
-               } else if (type == DESC_TYPE_COMPLEX) {
-                       /* this is a complex object */
-                       skip_size = safe_object_get_size ((MonoObject*)start);
-                       skip_size += (ALLOC_ALIGN - 1);
-                       skip_size &= ~(ALLOC_ALIGN - 1);
-                       OBJ_COMPLEX_FOREACH_PTR (vt, start);
-                       start += skip_size;
-                       type_complex++;
-                       continue;
-               } else if (type == DESC_TYPE_COMPLEX_ARR) {
-                       /* this is an array of complex structs */
-                       skip_size = safe_object_get_size ((MonoObject*)start);
-                       skip_size += (ALLOC_ALIGN - 1);
-                       skip_size &= ~(ALLOC_ALIGN - 1);
-                       OBJ_COMPLEX_ARR_FOREACH_PTR (vt, start);
-                       start += skip_size;
-                       type_complex++;
-                       continue;
-               } else {
-                       g_assert (0);
-               }
+
+#define SCAN_OBJECT_ACTION COUNT_OBJECT_TYPES
+#include "sgen-scan-object.h"
        }
        /*printf ("references to new nursery %p-%p (size: %dk): %d, checked: %d\n", old_start, end, (end-old_start)/1024, new_obj_references, obj_references_checked);
        printf ("\tstrings: %d, runl: %d, vector: %d, bitmaps: %d, lbitmaps: %d, complex: %d\n",
@@ -1395,10 +1351,7 @@ static void __attribute__((noinline))
 scan_area_for_domain (MonoDomain *domain, char *start, char *end)
 {
        GCVTable *vt;
-       size_t skip_size;
-       int type;
        gboolean remove;
-       mword desc;
 
        while (start < end) {
                if (!*(void**)start) {
@@ -1413,58 +1366,10 @@ scan_area_for_domain (MonoDomain *domain, char *start, char *end)
                        if (dislink)
                                mono_gc_register_disappearing_link (NULL, dislink, FALSE);
                }
-               desc = vt->desc;
-               type = desc & 0x7;
-               if (type == DESC_TYPE_STRING) {
-                       STRING_SIZE (skip_size, start);
-                       if (remove) memset (start, 0, skip_size);
-                       start += skip_size;
-                       continue;
-               } else if (type == DESC_TYPE_RUN_LENGTH) {
-                       OBJ_RUN_LEN_SIZE (skip_size, desc, start);
-                       g_assert (skip_size);
-                       if (remove) memset (start, 0, skip_size);
-                       start += skip_size;
-                       continue;
-               } else if (type == DESC_TYPE_VECTOR) { // includes ARRAY, too
-                       skip_size = safe_object_get_size ((MonoObject*)start);
-                       skip_size += (ALLOC_ALIGN - 1);
-                       skip_size &= ~(ALLOC_ALIGN - 1);
-                       if (remove) memset (start, 0, skip_size);
-                       start += skip_size;
-                       continue;
-               } else if (type == DESC_TYPE_SMALL_BITMAP) {
-                       OBJ_BITMAP_SIZE (skip_size, desc, start);
-                       g_assert (skip_size);
-                       if (remove) memset (start, 0, skip_size);
-                       start += skip_size;
-                       continue;
-               } else if (type == DESC_TYPE_LARGE_BITMAP) {
-                       skip_size = safe_object_get_size ((MonoObject*)start);
-                       skip_size += (ALLOC_ALIGN - 1);
-                       skip_size &= ~(ALLOC_ALIGN - 1);
-                       if (remove) memset (start, 0, skip_size);
-                       start += skip_size;
-                       continue;
-               } else if (type == DESC_TYPE_COMPLEX) {
-                       /* this is a complex object */
-                       skip_size = safe_object_get_size ((MonoObject*)start);
-                       skip_size += (ALLOC_ALIGN - 1);
-                       skip_size &= ~(ALLOC_ALIGN - 1);
-                       if (remove) memset (start, 0, skip_size);
-                       start += skip_size;
-                       continue;
-               } else if (type == DESC_TYPE_COMPLEX_ARR) {
-                       /* this is an array of complex structs */
-                       skip_size = safe_object_get_size ((MonoObject*)start);
-                       skip_size += (ALLOC_ALIGN - 1);
-                       skip_size &= ~(ALLOC_ALIGN - 1);
-                       if (remove) memset (start, 0, skip_size);
-                       start += skip_size;
-                       continue;
-               } else {
-                       g_assert (0);
-               }
+
+#define SCAN_OBJECT_NOSCAN
+#define SCAN_OBJECT_ACTION do { if (remove) memset (start, 0, skip_size); } while (0)
+#include "sgen-scan-object.h"
        }
 }
 
@@ -1731,75 +1636,9 @@ copy_object (char *obj, char *from_space_start, char *from_space_end)
 static char*
 scan_object (char *start, char* from_start, char* from_end)
 {
-       GCVTable *vt;
-       size_t skip_size;
-       mword desc;
-
-       vt = (GCVTable*)LOAD_VTABLE (start);
-       //type = vt->desc & 0x7;
+#include "sgen-scan-object.h"
 
-       /* gcc should be smart enough to remove the bounds check, but it isn't:( */
-       desc = vt->desc;
-       switch (desc & 0x7) {
-       //if (type == DESC_TYPE_STRING) {
-       case DESC_TYPE_STRING:
-               STRING_SIZE (skip_size, start);
-               return start + skip_size;
-       //} else if (type == DESC_TYPE_RUN_LENGTH) {
-       case DESC_TYPE_RUN_LENGTH:
-               OBJ_RUN_LEN_FOREACH_PTR (desc,start);
-               OBJ_RUN_LEN_SIZE (skip_size, desc, start);
-               g_assert (skip_size);
-               return start + skip_size;
-       //} else if (type == DESC_TYPE_VECTOR) { // includes ARRAY, too
-       case DESC_TYPE_ARRAY:
-       case DESC_TYPE_VECTOR:
-               OBJ_VECTOR_FOREACH_PTR (vt, start);
-               skip_size = safe_object_get_size ((MonoObject*)start);
-#if 0
-               skip_size = (vt->desc >> LOW_TYPE_BITS) & MAX_ELEMENT_SIZE;
-               skip_size *= mono_array_length ((MonoArray*)start);
-               skip_size += sizeof (MonoArray);
-#endif
-               skip_size += (ALLOC_ALIGN - 1);
-               skip_size &= ~(ALLOC_ALIGN - 1);
-               return start + skip_size;
-       //} else if (type == DESC_TYPE_SMALL_BITMAP) {
-       case DESC_TYPE_SMALL_BITMAP:
-               OBJ_BITMAP_FOREACH_PTR (desc,start);
-               OBJ_BITMAP_SIZE (skip_size, desc, start);
-               return start + skip_size;
-       //} else if (type == DESC_TYPE_LARGE_BITMAP) {
-       case DESC_TYPE_LARGE_BITMAP:
-               OBJ_LARGE_BITMAP_FOREACH_PTR (vt,start);
-               skip_size = safe_object_get_size ((MonoObject*)start);
-               skip_size += (ALLOC_ALIGN - 1);
-               skip_size &= ~(ALLOC_ALIGN - 1);
-               return start + skip_size;
-       //} else if (type == DESC_TYPE_COMPLEX) {
-       case DESC_TYPE_COMPLEX:
-               OBJ_COMPLEX_FOREACH_PTR (vt, start);
-               /* this is a complex object */
-               skip_size = safe_object_get_size ((MonoObject*)start);
-               skip_size += (ALLOC_ALIGN - 1);
-               skip_size &= ~(ALLOC_ALIGN - 1);
-               return start + skip_size;
-       //} else if (type == DESC_TYPE_COMPLEX_ARR) {
-       case DESC_TYPE_COMPLEX_ARR:
-               OBJ_COMPLEX_ARR_FOREACH_PTR (vt, start);
-               /* this is an array of complex structs */
-               skip_size = safe_object_get_size ((MonoObject*)start);
-#if 0
-               skip_size = mono_array_element_size (((MonoObject*)start)->vtable->klass);
-               skip_size *= mono_array_length ((MonoArray*)start);
-               skip_size += sizeof (MonoArray);
-#endif
-               skip_size += (ALLOC_ALIGN - 1);
-               skip_size &= ~(ALLOC_ALIGN - 1);
-               return start + skip_size;
-       }
-       g_assert_not_reached ();
-       return NULL;
+       return start;
 }
 
 /*
@@ -5825,10 +5664,7 @@ static void __attribute__((noinline))
 check_remsets_for_area (char *start, char *end)
 {
        GCVTable *vt;
-       size_t skip_size;
-       int type;
        int type_str = 0, type_rlen = 0, type_bitmap = 0, type_vector = 0, type_lbit = 0, type_complex = 0;
-       mword desc;
        new_obj_references = 0;
        obj_references_checked = 0;
        while (start < end) {
@@ -5842,64 +5678,9 @@ check_remsets_for_area (char *start, char *end)
                        MonoObject *obj = (MonoObject*)start;
                        g_print ("found at %p (0x%lx): %s.%s\n", start, (long)vt->desc, obj->vtable->klass->name_space, obj->vtable->klass->name);
                }
-               desc = vt->desc;
-               type = desc & 0x7;
-               if (type == DESC_TYPE_STRING) {
-                       STRING_SIZE (skip_size, start);
-                       start += skip_size;
-                       type_str++;
-                       continue;
-               } else if (type == DESC_TYPE_RUN_LENGTH) {
-                       OBJ_RUN_LEN_SIZE (skip_size, desc, start);
-                       g_assert (skip_size);
-                       OBJ_RUN_LEN_FOREACH_PTR (desc,start);
-                       start += skip_size;
-                       type_rlen++;
-                       continue;
-               } else if (type == DESC_TYPE_VECTOR) { // includes ARRAY, too
-                       skip_size = safe_object_get_size ((MonoObject*)start);
-                       skip_size += (ALLOC_ALIGN - 1);
-                       skip_size &= ~(ALLOC_ALIGN - 1);
-                       OBJ_VECTOR_FOREACH_PTR (vt, start);
-                       start += skip_size;
-                       type_vector++;
-                       continue;
-               } else if (type == DESC_TYPE_SMALL_BITMAP) {
-                       OBJ_BITMAP_SIZE (skip_size, desc, start);
-                       g_assert (skip_size);
-                       OBJ_BITMAP_FOREACH_PTR (desc,start);
-                       start += skip_size;
-                       type_bitmap++;
-                       continue;
-               } else if (type == DESC_TYPE_LARGE_BITMAP) {
-                       skip_size = safe_object_get_size ((MonoObject*)start);
-                       skip_size += (ALLOC_ALIGN - 1);
-                       skip_size &= ~(ALLOC_ALIGN - 1);
-                       OBJ_LARGE_BITMAP_FOREACH_PTR (vt,start);
-                       start += skip_size;
-                       type_lbit++;
-                       continue;
-               } else if (type == DESC_TYPE_COMPLEX) {
-                       /* this is a complex object */
-                       skip_size = safe_object_get_size ((MonoObject*)start);
-                       skip_size += (ALLOC_ALIGN - 1);
-                       skip_size &= ~(ALLOC_ALIGN - 1);
-                       OBJ_COMPLEX_FOREACH_PTR (vt, start);
-                       start += skip_size;
-                       type_complex++;
-                       continue;
-               } else if (type == DESC_TYPE_COMPLEX_ARR) {
-                       /* this is an array of complex structs */
-                       skip_size = safe_object_get_size ((MonoObject*)start);
-                       skip_size += (ALLOC_ALIGN - 1);
-                       skip_size &= ~(ALLOC_ALIGN - 1);
-                       OBJ_COMPLEX_ARR_FOREACH_PTR (vt, start);
-                       start += skip_size;
-                       type_complex++;
-                       continue;
-               } else {
-                       g_assert (0);
-               }
+
+#define SCAN_OBJECT_ACTION COUNT_OBJECT_TYPES
+#include "sgen-scan-object.h"
        }
 }
 
@@ -5946,60 +5727,12 @@ check_consistency (void)
 char*
 check_object (char *start)
 {
-       GCVTable *vt;
-       size_t skip_size;
-       mword desc;
-
        if (!start)
                return NULL;
 
-       vt = (GCVTable*)LOAD_VTABLE (start);
-       //type = vt->desc & 0x7;
+#include "sgen-scan-object.h"
 
-       desc = vt->desc;
-       switch (desc & 0x7) {
-       case DESC_TYPE_STRING:
-               STRING_SIZE (skip_size, start);
-               return start + skip_size;
-       case DESC_TYPE_RUN_LENGTH:
-               OBJ_RUN_LEN_FOREACH_PTR (desc,start);
-               OBJ_RUN_LEN_SIZE (skip_size, desc, start);
-               g_assert (skip_size);
-               return start + skip_size;
-       case DESC_TYPE_ARRAY:
-       case DESC_TYPE_VECTOR:
-               OBJ_VECTOR_FOREACH_PTR (vt, start);
-               skip_size = safe_object_get_size ((MonoObject*)start);
-               skip_size += (ALLOC_ALIGN - 1);
-               skip_size &= ~(ALLOC_ALIGN - 1);
-               return start + skip_size;
-       case DESC_TYPE_SMALL_BITMAP:
-               OBJ_BITMAP_FOREACH_PTR (desc,start);
-               OBJ_BITMAP_SIZE (skip_size, desc, start);
-               return start + skip_size;
-       case DESC_TYPE_LARGE_BITMAP:
-               OBJ_LARGE_BITMAP_FOREACH_PTR (vt,start);
-               skip_size = safe_object_get_size ((MonoObject*)start);
-               skip_size += (ALLOC_ALIGN - 1);
-               skip_size &= ~(ALLOC_ALIGN - 1);
-               return start + skip_size;
-       case DESC_TYPE_COMPLEX:
-               OBJ_COMPLEX_FOREACH_PTR (vt, start);
-               /* this is a complex object */
-               skip_size = safe_object_get_size ((MonoObject*)start);
-               skip_size += (ALLOC_ALIGN - 1);
-               skip_size &= ~(ALLOC_ALIGN - 1);
-               return start + skip_size;
-       case DESC_TYPE_COMPLEX_ARR:
-               OBJ_COMPLEX_ARR_FOREACH_PTR (vt, start);
-               /* this is an array of complex structs */
-               skip_size = safe_object_get_size ((MonoObject*)start);
-               skip_size += (ALLOC_ALIGN - 1);
-               skip_size &= ~(ALLOC_ALIGN - 1);
-               return start + skip_size;
-       }
-       g_assert_not_reached ();
-       return NULL;
+       return start;
 }
 
 /*
diff --git a/mono/metadata/sgen-scan-object.h b/mono/metadata/sgen-scan-object.h
new file mode 100644 (file)
index 0000000..1e12f71
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * Scans one object, using the OBJ_XXX macros.  The start of the
+ * object must be given in the variable "char* start".  Afterwards,
+ * "start" will point to the start of the next object.
+ *
+ * Modifiers (automatically undefined):
+ *
+ * SCAN_OBJECT_NOSCAN - if defined, don't actually scan the object,
+ * i.e. don't invoke the OBJ_XXX macros.
+ *
+ * SCAN_OBJECT_ACTION - is invoked after an object has been scanned.
+ * The object's start is "start", its length in bytes (including
+ * padding at the end) is "skip_size".  "desc" is the object's GC
+ * descriptor.
+ */
+
+#ifndef SCAN_OBJECT_ACTION
+#define SCAN_OBJECT_ACTION
+#endif
+
+{
+       GCVTable *vt;
+       size_t skip_size;
+       mword desc;
+
+       vt = (GCVTable*)LOAD_VTABLE (start);
+       //type = vt->desc & 0x7;
+
+       /* gcc should be smart enough to remove the bounds check, but it isn't:( */
+       desc = vt->desc;
+       switch (desc & 0x7) {
+       case DESC_TYPE_STRING:
+               STRING_SIZE (skip_size, start);
+               SCAN_OBJECT_ACTION;
+               start += skip_size;
+               break;
+       case DESC_TYPE_RUN_LENGTH:
+               OBJ_RUN_LEN_SIZE (skip_size, desc, start);
+               g_assert (skip_size);
+#ifndef SCAN_OBJECT_NOSCAN
+               OBJ_RUN_LEN_FOREACH_PTR (desc, start);
+#endif
+               SCAN_OBJECT_ACTION;
+               start += skip_size;
+               break;
+       case DESC_TYPE_ARRAY:
+       case DESC_TYPE_VECTOR:
+               skip_size = safe_object_get_size ((MonoObject*)start);
+               skip_size += (ALLOC_ALIGN - 1);
+               skip_size &= ~(ALLOC_ALIGN - 1);
+#ifndef SCAN_OBJECT_NOSCAN
+               OBJ_VECTOR_FOREACH_PTR (vt, start);
+#endif
+               SCAN_OBJECT_ACTION;
+               start += skip_size;
+               break;
+       case DESC_TYPE_SMALL_BITMAP:
+               OBJ_BITMAP_SIZE (skip_size, desc, start);
+               g_assert (skip_size);
+#ifndef SCAN_OBJECT_NOSCAN
+               OBJ_BITMAP_FOREACH_PTR (desc, start);
+#endif
+               SCAN_OBJECT_ACTION;
+               start += skip_size;
+               break;
+       case DESC_TYPE_LARGE_BITMAP:
+               skip_size = safe_object_get_size ((MonoObject*)start);
+               skip_size += (ALLOC_ALIGN - 1);
+               skip_size &= ~(ALLOC_ALIGN - 1);
+#ifndef SCAN_OBJECT_NOSCAN
+               OBJ_LARGE_BITMAP_FOREACH_PTR (vt,start);
+#endif
+               SCAN_OBJECT_ACTION;
+               start += skip_size;
+               break;
+       case DESC_TYPE_COMPLEX:
+               /* this is a complex object */
+               skip_size = safe_object_get_size ((MonoObject*)start);
+               skip_size += (ALLOC_ALIGN - 1);
+               skip_size &= ~(ALLOC_ALIGN - 1);
+#ifndef SCAN_OBJECT_NOSCAN
+               OBJ_COMPLEX_FOREACH_PTR (vt, start);
+#endif
+               SCAN_OBJECT_ACTION;
+               start += skip_size;
+               break;
+       case DESC_TYPE_COMPLEX_ARR:
+               /* this is an array of complex structs */
+               skip_size = safe_object_get_size ((MonoObject*)start);
+               skip_size += (ALLOC_ALIGN - 1);
+               skip_size &= ~(ALLOC_ALIGN - 1);
+#ifndef SCAN_OBJECT_NOSCAN
+               OBJ_COMPLEX_ARR_FOREACH_PTR (vt, start);
+#endif
+               SCAN_OBJECT_ACTION;
+               start += skip_size;
+               break;
+       default:
+               g_assert_not_reached ();
+       }
+}
+
+#undef SCAN_OBJECT_NOSCAN
+#undef SCAN_OBJECT_ACTION
index 4bc6db7340703b4560481c0c0e3ce0c9114661ed..0413ea4e833754cc0a851af2d52f2084e79c7c42 100644 (file)
@@ -1116,10 +1116,11 @@ mono_thread_pool_add (MonoObject *target, MonoMethodMessage *msg, MonoDelegate *
        ares = mono_async_result_new (domain, NULL, ac->state, NULL, (MonoObject*)ac);
        MONO_OBJECT_SETREF (ares, async_delegate, target);
 
-       if (domain->state == MONO_APPDOMAIN_UNLOADED || domain->state == MONO_APPDOMAIN_UNLOADING)
-               return ares;
-
        EnterCriticalSection (&ares_lock);
+       if (domain->state == MONO_APPDOMAIN_UNLOADED || domain->state == MONO_APPDOMAIN_UNLOADING) {
+               LeaveCriticalSection (&ares_lock);
+               return ares;
+       }
        mono_g_hash_table_insert (ares_htable, ares, ares);
        LeaveCriticalSection (&ares_lock);
 
@@ -1213,12 +1214,27 @@ mono_thread_pool_cleanup (void)
        socket_io_cleanup (&socket_io_data);
 }
 
+static void
+null_array (MonoArray *a, int first, int last)
+{
+       /* We must null the old array because it might
+          contain cross-appdomain references, which
+          will crash the GC when the domains are
+          unloaded. */
+       memset (mono_array_addr (a, MonoObject*, first), 0, sizeof (MonoObject*) * (last - first));
+}
+
 static void
 append_job (CRITICAL_SECTION *cs, TPQueue *list, MonoObject *ar)
 {
        threadpool_jobs_inc (ar); 
 
        EnterCriticalSection (cs);
+       if (ar->vtable->domain->state == MONO_APPDOMAIN_UNLOADING ||
+                       ar->vtable->domain->state == MONO_APPDOMAIN_UNLOADED) {
+               LeaveCriticalSection (cs);
+               return;
+       }
        if (list->array && (list->next_elem < mono_array_length (list->array))) {
                mono_array_setref (list->array, list->next_elem, ar);
                list->next_elem++;
@@ -1233,10 +1249,13 @@ append_job (CRITICAL_SECTION *cs, TPQueue *list, MonoObject *ar)
                /* slide the array or create a larger one if it's full */
                if (list->first_elem) {
                        mono_array_memcpy_refs (list->array, 0, list->array, list->first_elem, count);
+                       null_array (list->array, count, list->next_elem);
                } else {
+                       MonoArray *olda = list->array;
                        MonoArray *newa = mono_array_new_cached (mono_get_root_domain (), mono_defaults.object_class, mono_array_length (list->array) * 2);
                        mono_array_memcpy_refs (newa, 0, list->array, list->first_elem, count);
                        list->array = newa;
+                       null_array (olda, list->first_elem, list->next_elem);
                }
                list->first_elem = 0;
                list->next_elem = count;
@@ -1277,6 +1296,19 @@ clear_queue (CRITICAL_SECTION *cs, TPQueue *list, MonoDomain *domain)
        LeaveCriticalSection (cs);
 }
 
+static GSList *clear_ares_htable_entries = NULL;
+
+static void
+check_ares_htable_entry_for_domain (gpointer key, gpointer value, gpointer user_data)
+{
+       MonoObject *obj = key;
+       MonoDomain *domain = user_data;
+
+       g_assert (key == value);
+       if (obj->vtable->domain == domain)
+               clear_ares_htable_entries = g_slist_prepend (clear_ares_htable_entries, obj);
+}
+
 /*
  * Clean up the threadpool of all domain jobs.
  * Can only be called as part of the domain unloading process as
@@ -1288,6 +1320,9 @@ mono_thread_pool_remove_domain_jobs (MonoDomain *domain, int timeout)
        HANDLE sem_handle;
        int result = TRUE;
        guint32 start_time = 0;
+       GSList *list;
+
+       g_assert (domain->state == MONO_APPDOMAIN_UNLOADING);
 
        clear_queue (&mono_delegate_section, &async_call_queue, domain);
        clear_queue (&io_queue_lock, &async_io_queue, domain);
@@ -1318,6 +1353,16 @@ mono_thread_pool_remove_domain_jobs (MonoDomain *domain, int timeout)
 
        domain->cleanup_semaphore = NULL;
        CloseHandle (sem_handle);
+
+       EnterCriticalSection (&ares_lock);
+       g_assert (!clear_ares_htable_entries);
+       mono_g_hash_table_foreach (ares_htable, check_ares_htable_entry_for_domain, domain);
+       for (list = clear_ares_htable_entries; list; list = list->next)
+               mono_g_hash_table_remove (ares_htable, list->data);
+       g_slist_free (clear_ares_htable_entries);
+       clear_ares_htable_entries = NULL;
+       LeaveCriticalSection (&ares_lock);
+
        return result;
 }
 
@@ -1339,9 +1384,11 @@ dequeue_job (CRITICAL_SECTION *cs, TPQueue *list)
        count = list->next_elem - list->first_elem;
        /* reduce the size of the array if it's mostly empty */
        if (mono_array_length (list->array) > 16 && count < (mono_array_length (list->array) / 3)) {
+               MonoArray *olda = list->array;
                MonoArray *newa = mono_array_new_cached (mono_get_root_domain (), mono_defaults.object_class, mono_array_length (list->array) / 2);
                mono_array_memcpy_refs (newa, 0, list->array, list->first_elem, count);
                list->array = newa;
+               null_array (olda, list->first_elem, list->next_elem);
                list->first_elem = 0;
                list->next_elem = count;
        }
@@ -1353,6 +1400,8 @@ dequeue_job (CRITICAL_SECTION *cs, TPQueue *list)
 static void
 free_queue (TPQueue *list)
 {
+       if (list->array)
+               null_array (list->array, list->first_elem, list->next_elem);
        list->array = NULL;
        list->first_elem = list->next_elem = 0;
 }
index 9827cde757f9cd5f11b0d20134b6cbbb5246bce0..05100f536a1672406738b8fe6e86e55cf76415f5 100644 (file)
@@ -525,6 +525,17 @@ static void thread_cleanup (MonoThread *thread)
        thread->abort_exc = NULL;
        thread->current_appcontext = NULL;
 
+       /*
+        * This is necessary because otherwise we might have
+        * cross-domain references which will not get cleaned up when
+        * the target domain is unloaded.
+        */
+       if (thread->cached_culture_info) {
+               int i;
+               for (i = 0; i < NUM_CACHED_CULTURES * 2; ++i)
+                       mono_array_set (thread->cached_culture_info, MonoObject*, i, NULL);
+       }
+
        /* if the thread is not in the hash it has been removed already */
        if (!handle_remove (thread))
                return;
index 38b62cef9a3b19b82b9dfefe4e33f6ddb379b6c8..0b44cc8b8937e945a554fb0a91dc5e2a88e346cd 100644 (file)
@@ -798,23 +798,25 @@ mono_method_is_valid_in_context (VerifyContext *ctx, MonoMethod *method)
 
        
 static MonoClassField*
-verifier_load_field (VerifyContext *ctx, int token, MonoClass **klass, const char *opcode) {
+verifier_load_field (VerifyContext *ctx, int token, MonoClass **out_klass, const char *opcode) {
        MonoClassField *field;
-       
+       MonoClass *klass = NULL;
+
        if (!IS_FIELD_DEF_OR_REF (token) || !token_bounds_check (ctx->image, token)) {
                ADD_VERIFY_ERROR2 (ctx, g_strdup_printf ("Invalid field token 0x%x08x for %s at 0x%04x", token, opcode, ctx->ip_offset), MONO_EXCEPTION_BAD_IMAGE);
                return NULL;
        }
 
-       field = mono_field_from_token (ctx->image, token, klass, ctx->generic_context);
-       if (!field || !field->parent) {
+       field = mono_field_from_token (ctx->image, token, &klass, ctx->generic_context);
+       if (!field || !field->parent || !klass) {
                ADD_VERIFY_ERROR2 (ctx, g_strdup_printf ("Cannot load field from token 0x%08x for %s at 0x%04x", token, opcode, ctx->ip_offset), MONO_EXCEPTION_BAD_IMAGE);
                return NULL;
        }
 
-       if (!mono_type_is_valid_in_context (ctx, &field->parent->byval_arg))
+       if (!mono_type_is_valid_in_context (ctx, &klass->byval_arg))
                return NULL;
 
+       *out_klass = klass;
        return field;
 }
 
@@ -2048,7 +2050,7 @@ static MonoType*
 get_boxable_mono_type (VerifyContext* ctx, int token, const char *opcode)
 {
        MonoType *type;
-
+       MonoClass *class;
 
        if (!(type = verifier_load_type (ctx, token, opcode)))
                return NULL;
@@ -2066,6 +2068,12 @@ get_boxable_mono_type (VerifyContext* ctx, int token, const char *opcode)
        if (type->type == MONO_TYPE_TYPEDBYREF)
                CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Invalid use of typedbyref for %s at 0x%04x", opcode, ctx->ip_offset));
 
+       if (!(class = mono_class_from_mono_type (type)))
+               ADD_VERIFY_ERROR (ctx, g_strdup_printf ("Could not retrieve type token for %s at 0x%04x", opcode, ctx->ip_offset));
+
+       if (class->generic_container && type->type != MONO_TYPE_GENERICINST)
+               CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Cannot use the generic type definition in a boxable type position for %s at 0x%04x", opcode, ctx->ip_offset));      
+
        check_unverifiable_type (ctx, type);
        return type;
 }
index 95816bba3064ba05dbde92353aa60a9b7b8f68ea..f08751cf09db879d3e5d405c8a1fa470076afffb 100644 (file)
@@ -1,3 +1,83 @@
+2009-08-18  Zoltan Varga  <vargaz@gmail.com>
+
+       * aot-compiler.c (add_generic_instances): Fix the net 1.1 build.
+
+2009-08-18  Christian Hergert  <chris@dronelabs.com>
+
+       * method-to-ir.c: Fix warnings for uninitialized variables.
+
+2009-08-18  Christian Hergert  <chris@dronelabs.com>
+
+       * mini-exceptions.c:
+       * aot-compiler.c: Fix printf warnings.
+
+2009-08-18  Zoltan Varga  <vargaz@gmail.com>
+
+       * aot-compiler.c (add_generic_instances): Add string[] wrapper methods.
+       Add GetGenericValueImpl<string>.
+       
+       * aot-compiler.c (add_generic_instances): Add instances of
+       GenericEqualityComparer<T> for primitive types. Only emit the array
+       wrappers into the mscorlib image.
+
+2009-08-15  Zoltan Varga  <vargaz@gmail.com>
+
+       * aot-runtime.c (load_method): Rename 'aot_module' -> 'amodule'. Allocate
+       the methods_loaded array using amodule->info->nmethods.
+
+       * mini.h (MonoAotFileInfo): Add an 'nmethods' field.
+       (MONO_AOT_FILE_VERSION): Bump this.
+
+       * aot-compiler.c: Emit more generic instances allowing some parts of linq
+       to work.
+
+       * aot-runtime.c (mono_aot_get_unwind_info): Handle the case when the
+       MonoJitInfo doesn't belong to its methods aot image.
+
+2009-08-14  Zoltan Varga  <vargaz@gmail.com>
+
+       * mini-arm.c (mono_arch_allocate_vars): Use SP as the default frame reg.
+
+       * mini-arm.c: Fix warnings.
+       
+       * mini-arm.c (mono_arm_emit_load_imm): Only emit a movt if needed.
+
+       * mini-arm.c (mono_arm_emit_load_imm): Use movt/movw if the cpu
+       supports it.
+
+2009-08-12  Zoltan Varga  <vargaz@gmail.com>
+
+       * aot-compiler.c (arch_emit_imt_thunk): Rework the arm code to
+       avoid clobbering IP.
+
+       * mini-trampolines.c (mono_magic_trampoline): Allocate a local to
+       hold the trampoline argument, so its initial value is available during
+       debugging.
+
+2009-08-11 Gonzalo Paniagua Javier <gonzalo@novell.com>
+
+       * exceptions-arm.c:
+       * exceptions-hppa.c:
+       * mini.c:
+       * exceptions-s390x.c:
+       * exceptions-mips.c:
+       * exceptions-ppc.c:
+       * exceptions-sparc.c:
+       * exceptions-alpha.c:
+       * aot-runtime.c:
+       * mini-trampolines.c:
+       * exceptions-x86.c:
+       * exceptions-s390.c: add and use #define's instead of sizeof()
+       for MonoJitInfo and MonoJitInfoTable.
+
+2009-08-10 Gonzalo Paniagua Javier <gonzalo@novell.com>
+
+       * tramp-arm.c:
+       * tramp-amd64.c:
+       * tramp-ppc.c:
+       * tramp-x86.c: use a #define instead of sizeof() for a few
+       structures that use a zero-length array.
+
 2009-08-07  Rodrigo Kumpera  <rkumpera@novell.com>
 
        * method-to-ir.c (mono_method_to_ir/CEE_CONSTRAINED_): Handle the
index 601ad740b346295324a3b0b5e2407de3f967b4cc..46c45e45a69ce41fed133b141b6db31b6f7769fb 100644 (file)
@@ -1002,15 +1002,15 @@ arch_emit_imt_thunk (MonoAotCompile *acfg, int offset, int *tramp_size)
 
        /* The IMT method is in v5 */
 
-       /* Only IP is available, but we need at least two free registers */
-       ARM_PUSH1 (code, ARMREG_R1);
+       /* Need at least two free registers, plus a slot for storing the pc */
+       ARM_PUSH (code, (1 << ARMREG_R0)|(1 << ARMREG_R1)|(1 << ARMREG_R2));
        labels [0] = code;
        /* Load the parameter from the GOT */
-       ARM_LDR_IMM (code, ARMREG_IP, ARMREG_PC, 0);
-       ARM_LDR_REG_REG (code, ARMREG_IP, ARMREG_PC, ARMREG_IP);
+       ARM_LDR_IMM (code, ARMREG_R0, ARMREG_PC, 0);
+       ARM_LDR_REG_REG (code, ARMREG_R0, ARMREG_PC, ARMREG_R0);
 
        labels [1] = code;
-       ARM_LDR_IMM (code, ARMREG_R1, ARMREG_IP, 0);
+       ARM_LDR_IMM (code, ARMREG_R1, ARMREG_R0, 0);
        ARM_CMP_REG_REG (code, ARMREG_R1, ARMREG_V5);
        labels [2] = code;
        ARM_B_COND (code, ARMCOND_EQ, 0);
@@ -1021,16 +1021,19 @@ arch_emit_imt_thunk (MonoAotCompile *acfg, int offset, int *tramp_size)
        ARM_B_COND (code, ARMCOND_EQ, 0);
 
        /* Loop footer */
-       ARM_ADD_REG_IMM8 (code, ARMREG_IP, ARMREG_IP, sizeof (gpointer) * 2);
+       ARM_ADD_REG_IMM8 (code, ARMREG_R0, ARMREG_R0, sizeof (gpointer) * 2);
        labels [4] = code;
        ARM_B (code, 0);
        arm_patch (labels [4], labels [1]);
 
        /* Match */
        arm_patch (labels [2], code);
-       ARM_POP1 (code, ARMREG_R1);
-       ARM_LDR_IMM (code, ARMREG_IP, ARMREG_IP, 4);
-       ARM_LDR_IMM (code, ARMREG_PC, ARMREG_IP, 0);
+       ARM_LDR_IMM (code, ARMREG_R0, ARMREG_R0, 4);
+       ARM_LDR_IMM (code, ARMREG_R0, ARMREG_R0, 0);
+       /* Save it to the third stack slot */
+       ARM_STR_IMM (code, ARMREG_R0, ARMREG_SP, 8);
+       /* Restore the registers and branch */
+       ARM_POP (code, (1 << ARMREG_R0)|(1 << ARMREG_R1)|(1 << ARMREG_PC));
 
        /* No match */
        arm_patch (labels [3], code);
@@ -1038,7 +1041,7 @@ arch_emit_imt_thunk (MonoAotCompile *acfg, int offset, int *tramp_size)
 
        /* Fixup offset */
        code2 = labels [0];
-       ARM_LDR_IMM (code2, ARMREG_IP, ARMREG_PC, (code - (labels [0] + 8)));
+       ARM_LDR_IMM (code2, ARMREG_R0, ARMREG_PC, (code - (labels [0] + 8)));
 
        emit_bytes (acfg, buf, code - buf);
        emit_symbol_diff (acfg, acfg->got_symbol, ".", (offset * sizeof (gpointer)) + (code - (labels [0] + 8)) - 4);
@@ -2036,6 +2039,14 @@ add_generic_class (MonoAotCompile *acfg, MonoClass *klass)
                add_extra_method (acfg, method);
        }
 
+       if (klass->delegate) {
+               method = mono_get_delegate_invoke (klass);
+
+               method = mono_marshal_get_delegate_invoke (method, NULL);
+
+               add_method (acfg, method);
+       }
+
        /* 
         * For ICollection<T>, where T is a vtype, add instances of the helper methods
         * in Array, since a T[] could be cast to ICollection<T>.
@@ -2077,6 +2088,18 @@ add_generic_class (MonoAotCompile *acfg, MonoClass *klass)
        }
 }
 
+static void
+add_array_wrappers (MonoAotCompile *acfg, MonoClass *klass)
+{
+       int i;
+
+       mono_class_setup_methods (klass);
+       for (i = 0; i < klass->method.count; ++i) {
+               if (klass->methods [i]->wrapper_type == MONO_WRAPPER_MANAGED_TO_MANAGED)
+                       add_extra_method (acfg, klass->methods [i]);
+       }
+}
+
 /*
  * add_generic_instances:
  *
@@ -2188,6 +2211,85 @@ add_generic_instances (MonoAotCompile *acfg)
                        ctx.class_inst = mono_metadata_get_generic_inst (1, args);
                        add_generic_class (acfg, mono_class_inflate_generic_class (klass, &ctx));
                }
+
+               /* Add GenericEqualityComparer<T> instances for primitive types */
+               klass = mono_class_from_name (acfg->image, "System.Collections.Generic", "GenericEqualityComparer`1");
+
+               if (klass) {
+                       MonoGenericContext ctx;
+                       MonoType *args [16];
+
+                       memset (&ctx, 0, sizeof (ctx));
+
+                       args [0] = &mono_defaults.byte_class->byval_arg;
+                       ctx.class_inst = mono_metadata_get_generic_inst (1, args);
+                       add_generic_class (acfg, mono_class_inflate_generic_class (klass, &ctx));
+
+                       args [0] = &mono_defaults.sbyte_class->byval_arg;
+                       ctx.class_inst = mono_metadata_get_generic_inst (1, args);
+                       add_generic_class (acfg, mono_class_inflate_generic_class (klass, &ctx));
+
+                       args [0] = &mono_defaults.int16_class->byval_arg;
+                       ctx.class_inst = mono_metadata_get_generic_inst (1, args);
+                       add_generic_class (acfg, mono_class_inflate_generic_class (klass, &ctx));
+
+                       args [0] = &mono_defaults.uint16_class->byval_arg;
+                       ctx.class_inst = mono_metadata_get_generic_inst (1, args);
+                       add_generic_class (acfg, mono_class_inflate_generic_class (klass, &ctx));
+
+                       args [0] = &mono_defaults.int32_class->byval_arg;
+                       ctx.class_inst = mono_metadata_get_generic_inst (1, args);
+                       add_generic_class (acfg, mono_class_inflate_generic_class (klass, &ctx));
+
+                       args [0] = &mono_defaults.uint32_class->byval_arg;
+                       ctx.class_inst = mono_metadata_get_generic_inst (1, args);
+                       add_generic_class (acfg, mono_class_inflate_generic_class (klass, &ctx));
+
+                       args [0] = &mono_defaults.int64_class->byval_arg;
+                       ctx.class_inst = mono_metadata_get_generic_inst (1, args);
+                       add_generic_class (acfg, mono_class_inflate_generic_class (klass, &ctx));
+
+                       args [0] = &mono_defaults.uint64_class->byval_arg;
+                       ctx.class_inst = mono_metadata_get_generic_inst (1, args);
+                       add_generic_class (acfg, mono_class_inflate_generic_class (klass, &ctx));
+               }
+
+               /* Emit the array wrapper methods for arrays of primitive types */
+               add_array_wrappers (acfg, mono_array_class_get (mono_defaults.byte_class, 1));
+               add_array_wrappers (acfg, mono_array_class_get (mono_defaults.sbyte_class, 1));
+               add_array_wrappers (acfg, mono_array_class_get (mono_defaults.int16_class, 1));
+               add_array_wrappers (acfg, mono_array_class_get (mono_defaults.uint16_class, 1));
+               add_array_wrappers (acfg, mono_array_class_get (mono_defaults.int32_class, 1));
+               add_array_wrappers (acfg, mono_array_class_get (mono_defaults.uint32_class, 1));
+               add_array_wrappers (acfg, mono_array_class_get (mono_defaults.int64_class, 1));
+               add_array_wrappers (acfg, mono_array_class_get (mono_defaults.single_class, 1));
+               add_array_wrappers (acfg, mono_array_class_get (mono_defaults.double_class, 1));
+               /* These are not handled by generic sharing */
+               add_array_wrappers (acfg, mono_array_class_get (mono_defaults.object_class, 1));
+               add_array_wrappers (acfg, mono_array_class_get (mono_defaults.string_class, 1));
+
+               /* Add instances of Array.GetGenericValueImpl */
+               {
+                       MonoGenericContext ctx;
+                       MonoType *args [16];
+                       MonoMethod *method;
+
+                       memset (&ctx, 0, sizeof (ctx));
+
+                       /* 
+                        * managed-to-native wrappers are not shared, so have to generate 
+                        * these for ref types too.
+                        */
+                       klass = mono_array_class_get (mono_defaults.int_class, 1)->parent;
+                       method = mono_class_get_method_from_name (klass, "GetGenericValueImpl", 2);
+
+                       if (method) {
+                               /* String */
+                               args [0] = &mono_defaults.string_class->byval_arg;
+                               ctx.method_inst = mono_metadata_get_generic_inst (1, args);
+                               add_extra_method (acfg, mono_marshal_get_native_wrapper (mono_class_inflate_generic_method (method, &ctx), TRUE, TRUE));
+                       }
+               }
        }
 }
 
@@ -3595,6 +3697,13 @@ compile_method (MonoAotCompile *acfg, MonoMethod *method)
                        }
                        break;
                }
+               case MONO_PATCH_INFO_VTABLE: {
+                       MonoClass *klass = patch_info->data.klass;
+
+                       if (klass->generic_class && !mono_generic_context_is_sharable (&klass->generic_class->context, FALSE))
+                               add_generic_class (acfg, klass);
+                       break;
+               }
                default:
                        break;
                }
@@ -4609,7 +4718,7 @@ emit_got (MonoAotCompile *acfg)
        char symbol [256];
 
        /* Don't make GOT global so accesses to it don't need relocations */
-       sprintf (symbol, acfg->got_symbol);
+       sprintf (symbol, "%s", acfg->got_symbol);
        emit_section_change (acfg, ".bss", 0);
        emit_alignment (acfg, 8);
        emit_local_symbol (acfg, symbol, "got_end", FALSE);
@@ -4748,6 +4857,7 @@ emit_file_info (MonoAotCompile *acfg)
        emit_int32 (acfg, acfg->plt_got_offset_base);
        emit_int32 (acfg, (int)(acfg->got_offset * sizeof (gpointer)));
        emit_int32 (acfg, acfg->plt_offset);
+       emit_int32 (acfg, acfg->nmethods);
 
        for (i = 0; i < MONO_AOT_TRAMP_NUM; ++i)
                emit_int32 (acfg, acfg->num_trampolines [i]);
index b10051f8516fd87372221b16049066d15a10026d..ca03a21712a08b471236124f270b168c32af8f5e 100644 (file)
@@ -133,6 +133,12 @@ static CRITICAL_SECTION aot_mutex;
  */
 static GHashTable *static_aot_modules;
 
+/*
+ * Maps MonoJitInfo* to the aot module they belong to, this can be different
+ * from ji->method->klass->image's aot module for generic instances.
+ */
+static GHashTable *ji_to_amodule;
+
 /*
  * Whenever to AOT compile loaded assemblies on demand and store them in
  * a cache under $HOME/.mono/aot-cache.
@@ -1368,7 +1374,7 @@ mono_aot_get_class_from_name (MonoImage *image, const char *name_space, const ch
  * LOCKING: Acquires the domain lock.
  */
 static MonoJitInfo*
-decode_exception_debug_info (MonoAotModule *aot_module, MonoDomain *domain, 
+decode_exception_debug_info (MonoAotModule *amodule, MonoDomain *domain, 
                                                         MonoMethod *method, guint8* ex_info, guint8 *code)
 {
        int i, buf_len;
@@ -1405,7 +1411,7 @@ decode_exception_debug_info (MonoAotModule *aot_module, MonoDomain *domain,
        /* Exception table */
        if (header && header->num_clauses) {
                jinfo = 
-                       mono_domain_alloc0 (domain, sizeof (MonoJitInfo) + (sizeof (MonoJitExceptionInfo) * header->num_clauses) + generic_info_size);
+                       mono_domain_alloc0 (domain, MONO_SIZEOF_JIT_INFO + (sizeof (MonoJitExceptionInfo) * header->num_clauses) + generic_info_size);
                jinfo->num_clauses = header->num_clauses;
 
                for (i = 0; i < header->num_clauses; ++i) {
@@ -1426,7 +1432,7 @@ decode_exception_debug_info (MonoAotModule *aot_module, MonoDomain *domain,
                }
        }
        else {
-               jinfo = mono_domain_alloc0 (domain, sizeof (MonoJitInfo) + generic_info_size);
+               jinfo = mono_domain_alloc0 (domain, MONO_SIZEOF_JIT_INFO + generic_info_size);
        }
 
        jinfo->code_size = code_len;
@@ -1451,12 +1457,20 @@ decode_exception_debug_info (MonoAotModule *aot_module, MonoDomain *domain,
                /* This currently contains no data */
                gi->generic_sharing_context = g_new0 (MonoGenericSharingContext, 1);
 
-               jinfo->method = decode_method_ref_2 (aot_module, p, &p);
+               jinfo->method = decode_method_ref_2 (amodule, p, &p);
        }
 
        /* Load debug info */
        buf_len = decode_value (p, &p);
        mono_debug_add_aot_method (domain, method, code, p, buf_len);
+
+       if (amodule != jinfo->method->klass->image->aot_module) {
+               mono_aot_lock ();
+               if (!ji_to_amodule)
+                       ji_to_amodule = g_hash_table_new (NULL, NULL);
+               g_hash_table_insert (ji_to_amodule, jinfo, amodule);
+               mono_aot_unlock ();             
+       }
        
        return jinfo;
 }
@@ -1471,10 +1485,20 @@ mono_aot_get_unwind_info (MonoJitInfo *ji, guint32 *unwind_info_len)
 {
        MonoAotModule *amodule = ji->method->klass->image->aot_module;
        guint8 *p;
+       guint8 *code = ji->code_start;
 
        g_assert (amodule);
        g_assert (ji->from_aot);
 
+       if (!(code >= amodule->code && code <= amodule->code_end)) {
+               /* ji belongs to a different aot module than amodule */
+               mono_aot_lock ();
+               g_assert (ji_to_amodule);
+               amodule = g_hash_table_lookup (ji_to_amodule, ji);
+               g_assert (amodule);
+               g_assert (code >= amodule->code && code <= amodule->code_end);
+       }
+
        p = amodule->unwind_info + ji->used_regs;
        *unwind_info_len = decode_value (p, &p);
        return p;
@@ -1890,7 +1914,7 @@ register_jump_target_got_slot (MonoDomain *domain, MonoMethod *method, gpointer
  * METHOD might not be set if the caller only has the image/token info.
  */
 static gpointer
-load_method (MonoDomain *domain, MonoAotModule *aot_module, MonoImage *image, MonoMethod *method, guint32 token, int method_index)
+load_method (MonoDomain *domain, MonoAotModule *amodule, MonoImage *image, MonoMethod *method, guint32 token, int method_index)
 {
        MonoClass *klass;
        gboolean from_plt = method == NULL;
@@ -1904,14 +1928,14 @@ load_method (MonoDomain *domain, MonoAotModule *aot_module, MonoImage *image, Mo
        if (mono_profiler_get_events () & MONO_PROFILE_ENTER_LEAVE)
                return NULL;
 
-       if ((domain != mono_get_root_domain ()) && (!(aot_module->opts & MONO_OPT_SHARED)))
+       if ((domain != mono_get_root_domain ()) && (!(amodule->opts & MONO_OPT_SHARED)))
                /* Non shared AOT code can't be used in other appdomains */
                return NULL;
 
-       if (aot_module->out_of_date)
+       if (amodule->out_of_date)
                return NULL;
 
-       if (aot_module->code_offsets [method_index] == 0xffffffff) {
+       if (amodule->code_offsets [method_index] == 0xffffffff) {
                if (mono_trace_is_traced (G_LOG_LEVEL_DEBUG, MONO_TRACE_AOT)) {
                        char *full_name;
 
@@ -1924,15 +1948,15 @@ load_method (MonoDomain *domain, MonoAotModule *aot_module, MonoImage *image, Mo
                return NULL;
        }
 
-       code = &aot_module->code [aot_module->code_offsets [method_index]];
-       info = &aot_module->method_info [aot_module->method_info_offsets [method_index]];
+       code = &amodule->code [amodule->code_offsets [method_index]];
+       info = &amodule->method_info [amodule->method_info_offsets [method_index]];
 
        mono_aot_lock ();
-       if (!aot_module->methods_loaded)
-               aot_module->methods_loaded = g_new0 (guint32, image->tables [MONO_TABLE_METHOD].rows + 1);
+       if (!amodule->methods_loaded)
+               amodule->methods_loaded = g_new0 (guint32, amodule->info.nmethods + 1);
        mono_aot_unlock ();
 
-       if ((aot_module->methods_loaded [method_index / 32] >> (method_index % 32)) & 0x1)
+       if ((amodule->methods_loaded [method_index / 32] >> (method_index % 32)) & 0x1)
                return code;
 
        if (mono_last_aot_method != -1) {
@@ -1950,12 +1974,12 @@ load_method (MonoDomain *domain, MonoAotModule *aot_module, MonoImage *image, Mo
 
        if (method) {
                klass = method->klass;
-               decode_klass_ref (aot_module, p, &p);
+               decode_klass_ref (amodule, p, &p);
        } else {
-               klass = decode_klass_ref (aot_module, p, &p);
+               klass = decode_klass_ref (amodule, p, &p);
        }
 
-       if (aot_module->opts & MONO_OPT_SHARED)
+       if (amodule->opts & MONO_OPT_SHARED)
                used_strings = decode_value (p, &p);
        else
                used_strings = 0;
@@ -1965,7 +1989,7 @@ load_method (MonoDomain *domain, MonoAotModule *aot_module, MonoImage *image, Mo
                mono_ldstr (mono_get_root_domain (), image, mono_metadata_token_index (token));
        }
 
-       if (aot_module->opts & MONO_OPT_SHARED) 
+       if (amodule->opts & MONO_OPT_SHARED)    
                keep_patches = FALSE;
 
        n_patches = decode_value (p, &p);
@@ -1981,19 +2005,19 @@ load_method (MonoDomain *domain, MonoAotModule *aot_module, MonoImage *image, Mo
                else
                        mp = mono_mempool_new ();
 
-               patches = load_patch_info (aot_module, mp, n_patches, &got_slots, p, &p);
+               patches = load_patch_info (amodule, mp, n_patches, &got_slots, p, &p);
                if (patches == NULL)
                        goto cleanup;
 
                for (pindex = 0; pindex < n_patches; ++pindex) {
                        MonoJumpInfo *ji = &patches [pindex];
 
-                       if (!aot_module->got [got_slots [pindex]]) {
-                               aot_module->got [got_slots [pindex]] = mono_resolve_patch_target (method, domain, code, ji, TRUE);
+                       if (!amodule->got [got_slots [pindex]]) {
+                               amodule->got [got_slots [pindex]] = mono_resolve_patch_target (method, domain, code, ji, TRUE);
                                if (ji->type == MONO_PATCH_INFO_METHOD_JUMP)
-                                       aot_module->got [got_slots [pindex]] = mono_create_ftnptr (domain, aot_module->got [got_slots [pindex]]);
+                                       amodule->got [got_slots [pindex]] = mono_create_ftnptr (domain, amodule->got [got_slots [pindex]]);
                                if (ji->type == MONO_PATCH_INFO_METHOD_JUMP)
-                                       register_jump_target_got_slot (domain, ji->data.method, &(aot_module->got [got_slots [pindex]]));
+                                       register_jump_target_got_slot (domain, ji->data.method, &(amodule->got [got_slots [pindex]]));
                        }
                        ji->type = MONO_PATCH_INFO_NONE;
                }
@@ -2013,8 +2037,8 @@ load_method (MonoDomain *domain, MonoAotModule *aot_module, MonoImage *image, Mo
                full_name = mono_method_full_name (method, TRUE);
 
                if (!jinfo) {
-                       ex_info = &aot_module->ex_info [aot_module->ex_info_offsets [method_index]];
-                       jinfo = decode_exception_debug_info (aot_module, domain, method, ex_info, code);
+                       ex_info = &amodule->ex_info [amodule->ex_info_offsets [method_index]];
+                       jinfo = decode_exception_debug_info (amodule, domain, method, ex_info, code);
                }
 
                mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_AOT, "AOT FOUND AOT compiled code for %s %p - %p %p\n", full_name, code, code + jinfo->code_size, info);
@@ -2025,12 +2049,12 @@ load_method (MonoDomain *domain, MonoAotModule *aot_module, MonoImage *image, Mo
 
        mono_jit_stats.methods_aot++;
 
-       aot_module->methods_loaded [method_index / 32] |= 1 << (method_index % 32);
+       amodule->methods_loaded [method_index / 32] |= 1 << (method_index % 32);
 
-       init_plt (aot_module);
+       init_plt (amodule);
 
        if (method && method->wrapper_type)
-               g_hash_table_insert (aot_module->method_to_code, method, code);
+               g_hash_table_insert (amodule->method_to_code, method, code);
 
        mono_aot_unlock ();
 
@@ -2041,7 +2065,7 @@ load_method (MonoDomain *domain, MonoAotModule *aot_module, MonoImage *image, Mo
 
  cleanup:
        /* FIXME: The space in domain->mp is wasted */  
-       if (aot_module->opts & MONO_OPT_SHARED)
+       if (amodule->opts & MONO_OPT_SHARED)
                /* No need to cache patches */
                mono_mempool_destroy (mp);
 
index 65de48d11302b2d0bf1873631b57287954754e54..45f75b7332377ccf6fdbb7dacfe0e7a27a329a05 100644 (file)
@@ -59,7 +59,7 @@ static MonoDebuggerMetadataInfo debugger_metadata_info = {
        sizeof (MonoDebuggerMetadataInfo),
        sizeof (MonoDefaults),
        &mono_defaults,
-       sizeof (MonoType),
+       MONO_SIZEOF_TYPE,
        sizeof (MonoArrayType),
        sizeof (MonoClass),
        sizeof (MonoThread),
index 5de412c6664c8f8f1fe235d0e55bf5e36426e680..4a3a5bbcdd479b1e5dea660f6467f395281ca0f5 100644 (file)
@@ -977,7 +977,7 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls,
 
       if ((ji = mono_jit_info_table_find (domain, (gpointer)(*lmf)->eip))) {
       } else {
-       memset (res, 0, sizeof (MonoJitInfo));
+       memset (res, 0, MONO_SIZEOF_JIT_INFO);
        res->method = (*lmf)->method;
       }
 
index 94a0f3a34a2694cb63622f0c2879c0568dac1cd2..bebd9419835ebbba785c2303ab60623e6f2da364 100644 (file)
@@ -434,7 +434,7 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInf
                } else {
                        if (!(*lmf)->method)
                                return (gpointer)-1;
-                       memset (res, 0, sizeof (MonoJitInfo));
+                       memset (res, 0, MONO_SIZEOF_JIT_INFO);
                        res->method = (*lmf)->method;
                }
 
index afbe1b638f32a2379a12ab3d7c989cca5089293c..4b3f191fab11c49ea18bee02d40006391e596ba4 100644 (file)
@@ -579,7 +579,7 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInf
 
                if ((ji = mono_jit_info_table_find (domain, (gpointer)(*lmf)->eip))) {
                } else {
-                       memset (res, 0, sizeof (MonoJitInfo));
+                       memset (res, 0, MONO_SIZEOF_JIT_INFO);
                        res->method = (*lmf)->method;
                }
 
index b104152a16ee94aed88361b47ebd9c69dd2d9bda..13aff78f9de3f0b47a2541b7d32e58a4059ecfdb 100644 (file)
@@ -510,7 +510,7 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls,
 
                if ((ji = mono_jit_info_table_find (domain, (gpointer)(*lmf)->eip))) {
                } else {
-                       memset (res, 0, sizeof (MonoJitInfo));
+                       memset (res, 0, MONO_SIZEOF_JIT_INFO);
                        res->method = (*lmf)->method;
                }
                memcpy (&new_ctx->sc_regs, (*lmf)->iregs, sizeof (gulong) * MONO_SAVED_GREGS);
index 79189e078b978a402bdb13433123c0cb5b1c13a9..4dc0c6050c9bb4fa303b39c904ec92d70c674e5c 100644 (file)
@@ -609,7 +609,7 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInf
                        if (!(*lmf)->method)
                                return (gpointer)-1;
 
-                       memset (res, 0, sizeof (MonoJitInfo));
+                       memset (res, 0, MONO_SIZEOF_JIT_INFO);
                        res->method = (*lmf)->method;
                }
 
index e87d5f7f3677d3bdc26aaae667607b56b61df0d7..c2466f9784d53eac45aa39f108d91de733797751 100644 (file)
@@ -483,7 +483,7 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls,
 
                if ((ji = mono_jit_info_table_find (domain, (gpointer)(*lmf)->eip))) {
                } else {
-                       memset (res, 0, sizeof (MonoJitInfo));
+                       memset (res, 0, MONO_SIZEOF_JIT_INFO);
                        res->method = (*lmf)->method;
                }
 
index 4699b36803baf663c3a3d31816f76a68e8e443a7..5891e0ff6ecd4801a05faef3a1a8807109472dfe 100644 (file)
@@ -489,7 +489,7 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls,
 
                if ((ji = mono_jit_info_table_find (domain, (gpointer)(*lmf)->eip))) {
                } else {
-                       memset (res, 0, sizeof (MonoJitInfo));
+                       memset (res, 0, MONO_SIZEOF_JIT_INFO);
                        res->method = (*lmf)->method;
                }
 
index e721463495cf603d1ebbf0027ab7bcd9f30ac9d5..4f7640b5ce0b7c64b5cab25053ccaef1eeea5a4f 100644 (file)
@@ -414,7 +414,7 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInf
 
                if ((ji = mono_jit_info_table_find (domain, (gpointer)(*lmf)->ip))) {
                } else {
-                       memset (res, 0, sizeof (MonoJitInfo));
+                       memset (res, 0, MONO_SIZEOF_JIT_INFO);
                        res->method = (*lmf)->method;
                }
 
index 46b8e62ad11364d527e7da04b37e103a41f1a53a..f2d5eee568f9facc2bdf54308bd57c3fb9008ae0 100644 (file)
@@ -658,7 +658,7 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInf
                                /* Top LMF entry */
                                return (gpointer)-1;
                        /* Trampoline lmf frame */
-                       memset (res, 0, sizeof (MonoJitInfo));
+                       memset (res, 0, MONO_SIZEOF_JIT_INFO);
                        res->method = (*lmf)->method;
                }
 
index 65a83871932f6ccefa3ee0fb96cd2af7ded2e275..d9bed3b694c22450349a1c8cc5ced45e2586ca03 100644 (file)
@@ -2382,7 +2382,7 @@ static MonoInst*
 mono_emit_rgctx_method_call_full (MonoCompile *cfg, MonoMethod *method, MonoMethodSignature *sig,
                MonoInst **args, MonoInst *this, MonoInst *imt_arg, MonoInst *vtable_arg)
 {
-       int rgctx_reg;
+       int rgctx_reg = 0;
        MonoInst *ins;
        MonoCallInst *call;
 
@@ -10297,7 +10297,7 @@ mono_handle_global_vregs (MonoCompile *cfg)
                cfg->cbb = bb;
                for (; ins; ins = ins->next) {
                        const char *spec = INS_INFO (ins->opcode);
-                       int regtype, regindex;
+                       int regtype = 0, regindex;
                        gint32 prev_bb;
 
                        if (G_UNLIKELY (cfg->verbose_level > 2))
@@ -10306,7 +10306,7 @@ mono_handle_global_vregs (MonoCompile *cfg)
                        g_assert (ins->opcode >= MONO_CEE_LAST);
 
                        for (regindex = 0; regindex < 4; regindex ++) {
-                               int vreg;
+                               int vreg = 0;
 
                                if (regindex == 0) {
                                        regtype = spec [MONO_INST_DEST];
index be29c4a7379fb90833607b68e1693a0bb1e36a93..9f6c296cb56906041e821d3085fbd906cbfbdecc 100644 (file)
@@ -36,6 +36,7 @@ static gint lmf_addr_tls_offset = -1;
 static CRITICAL_SECTION mini_arch_mutex;
 
 static int v5_supported = 0;
+static int v7_supported = 0;
 static int thumb_supported = 0;
 
 /*
@@ -273,7 +274,7 @@ decode_vcall_slot_from_ldr (guint32 ldr, mgreg_t *regs, int *displacement)
        if (((ldr >> 23) & 1) == 0) /*U bit, 0 means negative and 1 positive*/
                offset = -offset;
        /*g_print ("found vcall at r%d + %d for code at %p 0x%x\n", reg, offset, code, *code);*/
-       o = regs [reg];
+       o = (gpointer)regs [reg];
 
        *displacement = offset;
        return o;
@@ -517,9 +518,10 @@ mono_arch_cpu_optimizazions (guint32 *exclude_mask)
                while ((line = fgets (buf, 512, file))) {
                        if (strncmp (line, "Processor", 9) == 0) {
                                char *ver = strstr (line, "(v");
-                               if (ver && (ver [2] == '5' || ver [2] == '6' || ver [2] == '7')) {
+                               if (ver && (ver [2] == '5' || ver [2] == '6' || ver [2] == '7'))
                                        v5_supported = TRUE;
-                               }
+                               if (ver && (ver [2] == '7'))
+                                       v7_supported = TRUE;
                                continue;
                        }
                        if (strncmp (line, "Features", 8) == 0) {
@@ -949,7 +951,7 @@ mono_arch_allocate_vars (MonoCompile *cfg)
        MonoMethodHeader *header;
        MonoInst *inst;
        int i, offset, size, align, curinst;
-       int frame_reg = ARMREG_FP;
+       int frame_reg = ARMREG_SP;
 
        /* FIXME: this will change when we use FP as gcc does */
        cfg->flags |= MONO_CFG_HAS_SPILLUP;
@@ -1996,7 +1998,6 @@ void
 mono_arch_decompose_long_opts (MonoCompile *cfg, MonoInst *long_ins)
 {
        MonoInst *ins;
-       int vreg;
 
        if (long_ins->opcode == OP_LNEG) {
                ins = long_ins;
@@ -2319,6 +2320,12 @@ mono_arm_emit_load_imm (guint8 *code, int dreg, guint32 val)
        } else if ((imm8 = mono_arm_is_rotated_imm8 (~val, &rot_amount)) >= 0) {
                ARM_MVN_REG_IMM (code, dreg, imm8, rot_amount);
        } else {
+               if (v7_supported) {
+                       ARM_MOVW_REG_IMM (code, dreg, val & 0xffff);
+                       if (val >> 16)
+                               ARM_MOVT_REG_IMM (code, dreg, (val >> 16) & 0xffff);
+                       return code;
+               }
                if (val & 0xFF) {
                        ARM_MOV_REG_IMM8 (code, dreg, (val & 0xFF));
                        if (val & 0xFF00) {
@@ -3414,7 +3421,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        break;
                case OP_LCONV_TO_OVF_I:
                case OP_LCONV_TO_OVF_I4_2: {
-                       guint32 *high_bit_not_set, *valid_negative, *invalid_negative, *valid_positive;
+                       guint8 *high_bit_not_set, *valid_negative, *invalid_negative, *valid_positive;
                        /* 
                         * Valid ints: 0xffffffff:8000000 to 00000000:0x7f000000
                         */
index f7b56a8511916c3eb7bd236ecbb137bdb5291d7a..1dc3ab9232d94306b1f6b18cd2235255507e36cb 100644 (file)
@@ -1643,7 +1643,7 @@ mono_print_thread_dump (void *sigctx)
        printf ("\t<Stack traces in thread dumps not supported on this platform>\n");
 #endif
 
-       fprintf (stdout, text->str);
+       fprintf (stdout, "%s", text->str);
        g_string_free (text, TRUE);
        fflush (stdout);
 }
index a7b102f50b3c733c335ab69003239dc5c8397f9e..3d29e912be618079cf367352bf15cbf45976449c 100644 (file)
@@ -200,17 +200,20 @@ mono_convert_imt_slot_to_vtable_slot (gpointer* slot, mgreg_t *regs, guint8 *cod
  *   This trampoline handles calls from JITted code.
  */
 gpointer
-mono_magic_trampoline (mgreg_t *regs, guint8 *code, MonoMethod *m, guint8* tramp)
+mono_magic_trampoline (mgreg_t *regs, guint8 *code, gpointer arg, guint8* tramp)
 {
        gpointer addr;
        gpointer *vtable_slot;
        gboolean generic_shared = FALSE;
+       MonoMethod *m;
        MonoMethod *declaring = NULL;
        MonoMethod *generic_virtual = NULL;
        int context_used;
        gboolean proxy = FALSE;
        gboolean need_rgctx_tramp = FALSE;
 
+       m = arg;
+
        if (m == MONO_FAKE_VTABLE_METHOD) {
                int displacement;
                MonoVTable *vt = mono_arch_get_vcall_slot (code, regs, &displacement);
@@ -1063,7 +1066,7 @@ mono_create_jump_trampoline (MonoDomain *domain, MonoMethod *method, gboolean ad
        code = mono_create_specific_trampoline (method, MONO_TRAMPOLINE_JUMP, mono_domain_get (), &code_size);
        g_assert (code_size);
 
-       ji = mono_domain_alloc0 (domain, sizeof (MonoJitInfo));
+       ji = mono_domain_alloc0 (domain, MONO_SIZEOF_JIT_INFO);
        ji->code_start = code;
        ji->code_size = code_size;
        ji->method = method;
index 4e3e877caabef51234a6bab7ef83262fe1fc7222..1342187acd0cbad51ed1c986facedab2532ed3ad 100644 (file)
@@ -3745,10 +3745,10 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, gbool
                generic_info_size = 0;
 
        if (cfg->method->dynamic) {
-               jinfo = g_malloc0 (sizeof (MonoJitInfo) + (header->num_clauses * sizeof (MonoJitExceptionInfo)) +
+               jinfo = g_malloc0 (MONO_SIZEOF_JIT_INFO + (header->num_clauses * sizeof (MonoJitExceptionInfo)) +
                                generic_info_size);
        } else {
-               jinfo = mono_domain_alloc0 (cfg->domain, sizeof (MonoJitInfo) +
+               jinfo = mono_domain_alloc0 (cfg->domain, MONO_SIZEOF_JIT_INFO +
                                (header->num_clauses * sizeof (MonoJitExceptionInfo)) +
                                generic_info_size);
        }
index 923522da206745a9890b37763af8bd733b9bf9e7..0b514e3d12ed8ac5f18948633b4b06ef574873af 100644 (file)
@@ -89,7 +89,7 @@ typedef gint64 mgreg_t;
 #endif
 
 /* Version number of the AOT file format */
-#define MONO_AOT_FILE_VERSION "57"
+#define MONO_AOT_FILE_VERSION "58"
 
 //TODO: This is x86/amd64 specific.
 #define mono_simd_shuffle_mask(a,b,c,d) ((a) | ((b) << 2) | ((c) << 4) | ((d) << 6))
@@ -124,6 +124,7 @@ typedef struct MonoAotFileInfo
        guint32 plt_got_offset_base;
        guint32 got_size;
        guint32 plt_size;
+       guint32 nmethods;
 
        guint32 num_trampolines [MONO_AOT_TRAMP_NUM];
        guint32 trampoline_got_offset_base [MONO_AOT_TRAMP_NUM];
@@ -1475,7 +1476,7 @@ gpointer          mono_create_static_rgctx_trampoline (MonoMethod *m, gpointer a
 gpointer          mono_create_llvm_vcall_trampoline (MonoMethod *method) MONO_INTERNAL;
 MonoVTable*       mono_find_class_init_trampoline_by_addr (gconstpointer addr) MONO_INTERNAL;
 guint32           mono_find_rgctx_lazy_fetch_trampoline_by_addr (gconstpointer addr) MONO_INTERNAL;
-gpointer          mono_magic_trampoline (mgreg_t *regs, guint8 *code, MonoMethod *m, guint8* tramp) MONO_INTERNAL;
+gpointer          mono_magic_trampoline (mgreg_t *regs, guint8 *code, gpointer arg, guint8* tramp) MONO_INTERNAL;
 gpointer          mono_generic_virtual_remoting_trampoline (mgreg_t *regs, guint8 *code, MonoMethod *m, guint8 *tramp) MONO_INTERNAL;
 gpointer          mono_delegate_trampoline (mgreg_t *regs, guint8 *code, gpointer *tramp_data, guint8* tramp) MONO_INTERNAL;
 gpointer          mono_aot_trampoline (mgreg_t *regs, guint8 *code, guint8 *token_info, 
index 1a8988cb565214b268bf7fb9186fafe97ed45c97..014102eaef46eec80eff64750a1d9aafe87707da 100644 (file)
@@ -633,7 +633,7 @@ mono_arch_create_rgctx_lazy_fetch_trampoline_full (guint32 slot, guint32 *code_s
        mrgctx = MONO_RGCTX_SLOT_IS_MRGCTX (slot);
        index = MONO_RGCTX_SLOT_INDEX (slot);
        if (mrgctx)
-               index += sizeof (MonoMethodRuntimeGenericContext) / sizeof (gpointer);
+               index += MONO_SIZEOF_METHOD_RUNTIME_GENERIC_CONTEXT / sizeof (gpointer);
        for (depth = 0; ; ++depth) {
                int size = mono_class_rgctx_get_array_size (depth, mrgctx);
 
@@ -664,7 +664,7 @@ mono_arch_create_rgctx_lazy_fetch_trampoline_full (guint32 slot, guint32 *code_s
        for (i = 0; i < depth; ++i) {
                /* load ptr to next array */
                if (mrgctx && i == 0)
-                       amd64_mov_reg_membase (code, AMD64_RAX, AMD64_RAX, sizeof (MonoMethodRuntimeGenericContext), 8);
+                       amd64_mov_reg_membase (code, AMD64_RAX, AMD64_RAX, MONO_SIZEOF_METHOD_RUNTIME_GENERIC_CONTEXT, 8);
                else
                        amd64_mov_reg_membase (code, AMD64_RAX, AMD64_RAX, 0, 8);
                /* is the ptr null? */
index c2e2124ee98b4ac9ac345bc0ab67305a8fab5911..1a6d5bde32ce04352f99942f5cca060c3f8642fb 100644 (file)
@@ -524,7 +524,7 @@ mono_arch_create_rgctx_lazy_fetch_trampoline_full (guint32 slot, guint32 *code_s
        mrgctx = MONO_RGCTX_SLOT_IS_MRGCTX (slot);
        index = MONO_RGCTX_SLOT_INDEX (slot);
        if (mrgctx)
-               index += sizeof (MonoMethodRuntimeGenericContext) / sizeof (gpointer);
+               index += MONO_SIZEOF_METHOD_RUNTIME_GENERIC_CONTEXT / sizeof (gpointer);
        for (depth = 0; ; ++depth) {
                int size = mono_class_rgctx_get_array_size (depth, mrgctx);
 
@@ -560,8 +560,8 @@ mono_arch_create_rgctx_lazy_fetch_trampoline_full (guint32 slot, guint32 *code_s
        for (i = 0; i < depth; ++i) {
                /* load ptr to next array */
                if (mrgctx && i == 0) {
-                       g_assert (arm_is_imm12 (sizeof (MonoMethodRuntimeGenericContext)));
-                       ARM_LDR_IMM (code, ARMREG_R1, ARMREG_R1, sizeof (MonoMethodRuntimeGenericContext));
+                       g_assert (arm_is_imm12 (MONO_SIZEOF_METHOD_RUNTIME_GENERIC_CONTEXT));
+                       ARM_LDR_IMM (code, ARMREG_R1, ARMREG_R1, MONO_SIZEOF_METHOD_RUNTIME_GENERIC_CONTEXT);
                } else {
                        ARM_LDR_IMM (code, ARMREG_R1, ARMREG_R1, 0);
                }
index 694392c136514b1e484d05ac6db910f3d3343865..7f48cb716db57abb7cfc9dc77117d003657463ef 100644 (file)
@@ -560,7 +560,7 @@ mono_arch_create_rgctx_lazy_fetch_trampoline_full (guint32 slot, guint32 *code_s
        mrgctx = MONO_RGCTX_SLOT_IS_MRGCTX (slot);
        index = MONO_RGCTX_SLOT_INDEX (slot);
        if (mrgctx)
-               index += sizeof (MonoMethodRuntimeGenericContext) / sizeof (gpointer);
+               index += MONO_SIZEOF_METHOD_RUNTIME_GENERIC_CONTEXT / sizeof (gpointer);
        for (depth = 0; ; ++depth) {
                int size = mono_class_rgctx_get_array_size (depth, mrgctx);
 
@@ -597,7 +597,7 @@ mono_arch_create_rgctx_lazy_fetch_trampoline_full (guint32 slot, guint32 *code_s
        for (i = 0; i < depth; ++i) {
                /* load ptr to next array */
                if (mrgctx && i == 0)
-                       ppc_ldptr (code, ppc_r4, sizeof (MonoMethodRuntimeGenericContext), ppc_r4);
+                       ppc_ldptr (code, ppc_r4, MONO_SIZEOF_METHOD_RUNTIME_GENERIC_CONTEXT, ppc_r4);
                else
                        ppc_ldptr (code, ppc_r4, 0, ppc_r4);
                /* is the ptr null? */
index 4234cd8806f742aa1dacff89dadc19a6c824a709..0ff20a1860ee875b6ad7f00a3417b43d88a85a96 100644 (file)
@@ -452,7 +452,7 @@ mono_arch_create_rgctx_lazy_fetch_trampoline (guint32 slot)
        mrgctx = MONO_RGCTX_SLOT_IS_MRGCTX (slot);
        index = MONO_RGCTX_SLOT_INDEX (slot);
        if (mrgctx)
-               index += sizeof (MonoMethodRuntimeGenericContext) / sizeof (gpointer);
+               index += MONO_SIZEOF_METHOD_RUNTIME_GENERIC_CONTEXT / sizeof (gpointer);
        for (depth = 0; ; ++depth) {
                int size = mono_class_rgctx_get_array_size (depth, mrgctx);
 
@@ -482,7 +482,7 @@ mono_arch_create_rgctx_lazy_fetch_trampoline (guint32 slot)
        for (i = 0; i < depth; ++i) {
                /* load ptr to next array */
                if (mrgctx && i == 0)
-                       x86_mov_reg_membase (buf, X86_EAX, X86_EAX, sizeof (MonoMethodRuntimeGenericContext), 4);
+                       x86_mov_reg_membase (buf, X86_EAX, X86_EAX, MONO_SIZEOF_METHOD_RUNTIME_GENERIC_CONTEXT, 4);
                else
                        x86_mov_reg_membase (buf, X86_EAX, X86_EAX, 0, 4);
                /* is the ptr null? */
index fc0a5fa8db84d9bdf9d1ec9b07919c557c9d6c80..b1b5d5dee231edab27f596ec6ebd17ddb53959dd 100644 (file)
@@ -1,3 +1,6 @@
+2009-08-18  Christian Hergert  <chris@dronelabs.com>
+
+       * monograph.c: Fix printf warnings.
 
 Mon Sep 10 15:03:06 CEST 2007 Paolo Molaro <lupus@ximian.com>
 
index 397b8f22af403d3f60e6b64f3f9a61accab91071..5451b8b54f33146c699460c7f89329d88f65fa5f 100644 (file)
@@ -934,9 +934,9 @@ df_visit (MonoBasicBlock *bb, int *dfn, const unsigned char* code)
                next = tmp->data;
                if (!next->dfn) {
                        if (!bb->cil_code)
-                               fprintf (output, "\t\"DF entry\" -> \"IL_%04x (%d)\"\n", next->cil_code - code, *dfn + 1);
+                               fprintf (output, "\t\"DF entry\" -> \"IL_%04x (%d)\"\n", (unsigned int)(next->cil_code - code), *dfn + 1);
                        else
-                               fprintf (output, "\t\"IL_%04x (%d)\" -> \"IL_%04x (%d)\"\n", bb->cil_code - code, bb->dfn, next->cil_code - code, *dfn + 1);
+                               fprintf (output, "\t\"IL_%04x (%d)\" -> \"IL_%04x (%d)\"\n", (unsigned int)(bb->cil_code - code), bb->dfn, (unsigned int)(next->cil_code - code), *dfn + 1);
                        df_visit (next, dfn, code);
                }
        }
@@ -963,7 +963,7 @@ print_method_cfg (MonoMethod *method) {
                        fprintf (output, "\tB%p [shape=record,label=\"end\"]\n", bb);
                else {
                        code = mono_disasm_code (&graph_dh, method, bb->cil_code, bb->cil_code + bb->cil_length);
-                       fprintf (output, "\tB%p [shape=record,label=\"IL_%04x\\n%s\"]\n", bb, bb->cil_code - il_code, code);
+                       fprintf (output, "\tB%p [shape=record,label=\"IL_%04x\\n%s\"]\n", bb, (unsigned int)(bb->cil_code - il_code), code);
                        g_free (code);
                }
        }
index 67f34caf046148deaa97820063f68fad4c27b0d1..ad5e1a60513e811f65f6f2a2d59e1eca16bc10a0 100644 (file)
@@ -1,3 +1,18 @@
+2009-08-18  Christian Hergert  <chris@dronelabs.com>
+
+       * mono-profiler-aot.c:
+       * mono-cov.c: Add missing method declarations.
+
+2009-08-14  Massimiliano Mantione <massi@ximian.com>
+       * mono-profiler-logging.c (disable_profiler):
+       Flush buffers synchronously so the GUI knows when we are done.
+
+2009-08-14  Massimiliano Mantione <massi@ximian.com>
+       * mono-profiler-logging.c:
+       - Added user thread reading commands from a local tcp port.
+       - Fixed file flushing after writing a block.
+       - Force full buffer flushing after disabling the profiler.
+
 2009-08-06  Massimiliano Mantione <massi@ximian.com>
        * mono-profiler-logging.c:
        - Avoid registering the writer thread with the runtime unless when
index d7e186b9d9813aa279a0a9cbee501dffff34d8f7..bed8c25d9d55087c3667dd8e83096411b16724d7 100644 (file)
@@ -124,6 +124,9 @@ cov_method_leave (MonoProfiler *prof, MonoMethod *method)
 {
 }
 
+void
+mono_profiler_startup (const char *desc);
+
 /* the entry point */
 void
 mono_profiler_startup (const char *desc)
index acab7545afb024d4522ae92e71c6e3b2da072cbe..9b7715253267707f3d2f8b08b780c51857c647c2 100644 (file)
@@ -124,6 +124,9 @@ prof_jit_leave (MonoProfiler *prof, MonoMethod *method, int result)
        data->methods = g_list_append (data->methods, method);
 }
 
+void
+mono_profiler_startup (const char *desc);
+
 /* the entry point */
 void
 mono_profiler_startup (const char *desc)
index b6c286260ce71035b63e7ee8378c3587de9ecadf..cb66de14941fe41080751816e09921e665db6ef8 100644 (file)
 
 #include <dlfcn.h>
 
+#include <sys/types.h> 
+#include <sys/socket.h>
+#include <netinet/in.h>
+
 #define HAS_OPROFILE 0
 
 #if (HAS_OPROFILE)
@@ -693,6 +697,7 @@ typedef struct _ProfilerExecutableFiles {
 
 #define THREAD_TYPE pthread_t
 #define CREATE_WRITER_THREAD(f) pthread_create (&(profiler->data_writer_thread), NULL, ((void*(*)(void*))f), NULL)
+#define CREATE_USER_THREAD(f) pthread_create (&(profiler->user_thread), NULL, ((void*(*)(void*))f), NULL)
 #define EXIT_THREAD() pthread_exit (NULL);
 #define WAIT_WRITER_THREAD() do {\
        if (CHECK_WRITER_THREAD ()) {\
@@ -741,13 +746,13 @@ make_pthread_profiler_key (void) {
 #define OPEN_FILE() profiler->file = fopen (profiler->file_name, "wb");
 #define WRITE_BUFFER(b,s) fwrite ((b), 1, (s), profiler->file)
 #define FLUSH_FILE() fflush (profiler->file)
-#define CLOSE_FILE() fclose (profiler->file);
+#define CLOSE_FILE() fclose (profiler->file)
 #else
 #define FILE_HANDLE_TYPE int
 #define OPEN_FILE() profiler->file = open (profiler->file_name, O_WRONLY|O_CREAT|O_TRUNC, 0664);
 #define WRITE_BUFFER(b,s) write (profiler->file, (b), (s))
-#define FLUSH_FILE()
-#define CLOSE_FILE() close (profiler->file);
+#define FLUSH_FILE() fsync (profiler->file)
+#define CLOSE_FILE() close (profiler->file)
 #endif
 
 #else
@@ -875,6 +880,7 @@ struct _MonoProfiler {
        ProfilerCodeChunks code_chunks;
        
        THREAD_TYPE data_writer_thread;
+       THREAD_TYPE user_thread;
        EVENT_TYPE enable_data_writer_event;
        EVENT_TYPE wake_data_writer_event;
        EVENT_TYPE done_data_writer_event;
@@ -890,6 +896,8 @@ struct _MonoProfiler {
        ProfilerHeapShotWriteJob *heap_shot_write_jobs;
        ProfilerHeapShotHeapBuffers heap;
        
+       int command_port;
+       
        char *heap_shot_command_file_name;
        int dump_next_heap_snapshots;
        guint64 heap_shot_command_file_access_time;
@@ -963,9 +971,12 @@ enable_profiler (void) {
        profiler->profiler_enabled = TRUE;
 }
 
+static void flush_everything (void);
+
 static void
 disable_profiler (void) {
        profiler->profiler_enabled = FALSE;
+       flush_everything ();
 }
 
 
@@ -1007,12 +1018,18 @@ add_toggle_handler (int signal_number)
 #define DEBUG_CLASS_BITMAPS 0
 #define DEBUG_STATISTICAL_PROFILER 0
 #define DEBUG_WRITER_THREAD 0
+#define DEBUG_USER_THREAD 0
 #define DEBUG_FILE_WRITES 0
 #if (DEBUG_LOGGING_PROFILER || DEBUG_STATISTICAL_PROFILER || DEBUG_HEAP_PROFILER || DEBUG_WRITER_THREAD || DEBUG_FILE_WRITES)
 #define LOG_WRITER_THREAD(m) printf ("WRITER-THREAD-LOG %s\n", m)
 #else
 #define LOG_WRITER_THREAD(m)
 #endif
+#if (DEBUG_LOGGING_PROFILER || DEBUG_STATISTICAL_PROFILER || DEBUG_HEAP_PROFILER || DEBUG_USER_THREAD || DEBUG_FILE_WRITES)
+#define LOG_USER_THREAD(m) printf ("USER-THREAD-LOG %s\n", m)
+#else
+#define LOG_USER_THREAD(m)
+#endif
 
 #if DEBUG_LOGGING_PROFILER
 static int event_counter = 0;
@@ -5217,6 +5234,148 @@ runtime_initialized (MonoProfiler *profiler) {
        LOG_WRITER_THREAD ("runtime_initialized: initialized internal calls.\n");
 }
 
+
+#define MAX_COMMAND_LENGTH (1024)
+static int server_socket;
+static int command_socket;
+
+static void
+write_user_response (const char *response) {
+       LOG_USER_THREAD ("write_user_response: writing response:");
+       LOG_USER_THREAD (response);
+       send (command_socket, response, strlen (response), 0);
+}
+
+static void
+execute_user_command (char *command) {
+       char *line_feed;
+       
+       LOG_USER_THREAD ("execute_user_command: executing command:");
+       LOG_USER_THREAD (command);
+       
+       /* Ignore leading and trailing '\r' */
+       line_feed = strchr (command, '\r');
+       if (line_feed == command) {
+               command ++;
+               line_feed = strchr (command, '\r');
+       }
+       if ((line_feed != NULL) && (* (line_feed + 1) == 0)) {
+               *line_feed = 0;
+       }
+       
+       if (strcmp (command, "enable") == 0) {
+               LOG_USER_THREAD ("execute_user_command: enabling profiler");
+               enable_profiler ();
+               write_user_response ("DONE\n");
+       } else if (strcmp (command, "disable") == 0) {
+               LOG_USER_THREAD ("execute_user_command: disabling profiler");
+               disable_profiler ();
+               write_user_response ("DONE\n");
+       } else {
+               LOG_USER_THREAD ("execute_user_command: command not recognized");
+               write_user_response ("ERROR\n");
+       }
+}
+
+static gboolean
+process_user_commands (void) {
+       char *command_buffer = malloc (MAX_COMMAND_LENGTH);
+       int command_buffer_current_index = 0;
+       gboolean loop = TRUE;
+       gboolean result = TRUE;
+       
+       while (loop) {
+               int unprocessed_characters;
+               
+               LOG_USER_THREAD ("process_user_commands: reading from socket...");
+               unprocessed_characters = recv (command_socket, command_buffer + command_buffer_current_index, MAX_COMMAND_LENGTH - command_buffer_current_index, 0);
+               
+               if (unprocessed_characters > 0) {
+                       char *command_end = NULL;
+                       
+                       LOG_USER_THREAD ("process_user_commands: received characters.");
+                       
+                       do {
+                               if (command_end != NULL) {
+                                       *command_end = 0;
+                                       execute_user_command (command_buffer);
+                                       unprocessed_characters -= (((command_end - command_buffer) - command_buffer_current_index) + 1);
+                                       
+                                       if (unprocessed_characters > 0) {
+                                               memmove (command_buffer, command_end + 1, unprocessed_characters);
+                                       }
+                                       command_buffer_current_index = 0;
+                               }
+                               
+                               command_end = memchr (command_buffer, '\n', command_buffer_current_index + unprocessed_characters);
+                       } while (command_end != NULL);
+                       
+                       command_buffer_current_index += unprocessed_characters;
+                       
+               } else if (unprocessed_characters == 0) {
+                       LOG_USER_THREAD ("process_user_commands: received no character.");
+                       result = TRUE;
+                       loop = FALSE;
+               } else {
+                       LOG_USER_THREAD ("process_user_commands: received error.");
+                       result = FALSE;
+                       loop = FALSE;
+               }
+       }
+       
+       free (command_buffer);
+       return result;
+}
+
+static guint32
+user_thread (gpointer nothing) {
+       struct sockaddr_in server_address;
+       
+       server_socket = -1;
+       command_socket = -1;
+       
+       LOG_USER_THREAD ("user_thread: starting up...");
+       
+       server_socket = socket (AF_INET, SOCK_STREAM, 0);
+       if (server_socket < 0) {
+               LOG_USER_THREAD ("user_thread: error creating socket.");
+               return 0;
+       }
+       memset (& server_address, 0, sizeof (server_address));
+       
+       server_address.sin_family = AF_INET;
+       server_address.sin_addr.s_addr = INADDR_ANY;
+       if ((profiler->command_port < 1023) || (profiler->command_port > 65535)) {
+               LOG_USER_THREAD ("user_thread: invalid port number.");
+               return 0;
+       }
+       server_address.sin_port = htons (profiler->command_port);
+       
+       if (bind (server_socket, (struct sockaddr *) &server_address, sizeof(server_address)) < 0) {
+               LOG_USER_THREAD ("user_thread: error binding socket.");
+               close (server_socket);
+               return 0;
+       }
+       
+       LOG_USER_THREAD ("user_thread: listening...\n");
+       listen (server_socket, 1);
+       command_socket = accept (server_socket, NULL, NULL);
+       if (command_socket < 0) {
+               LOG_USER_THREAD ("user_thread: error accepting socket.");
+               close (server_socket);
+               return 0;
+       }
+       
+       LOG_USER_THREAD ("user_thread: processing user commands...");
+       process_user_commands ();
+       
+       LOG_USER_THREAD ("user_thread: exiting cleanly.");
+       close (server_socket);
+       close (command_socket);
+       return 0;
+}
+
+
 /* called at the end of the program */
 static void
 profiler_shutdown (MonoProfiler *prof)
@@ -5465,6 +5624,11 @@ setup_user_options (const char *arguments) {
                                if (strlen (equals + 1) > 0) {
                                        profiler->dump_next_heap_snapshots = atoi (equals + 1);
                                }
+                       } else if (! (strncmp (argument, "command-port", equals_position) && strncmp (argument, "cp", equals_position))) {
+                               FAIL_IF_HAS_MINUS;
+                               if (strlen (equals + 1) > 0) {
+                                       profiler->command_port = atoi (equals + 1);
+                               }
 #ifndef PLATFORM_WIN32
                        } else if (! (strncmp (argument, "toggle-signal", equals_position) && strncmp (argument, "ts", equals_position))) {
                                FAIL_IF_HAS_MINUS;
@@ -5717,6 +5881,13 @@ data_writer_thread (gpointer nothing) {
                        
                        UNLOCK_PROFILER ();
                        LOG_WRITER_THREAD ("data_writer_thread: wrote data and released lock");
+               } else {
+                       LOG_WRITER_THREAD ("data_writer_thread: acquiring lock and flushing buffers");
+                       LOCK_PROFILER ();
+                       LOG_WRITER_THREAD ("data_writer_thread: lock acquired, flushing buffers");
+                       flush_everything ();
+                       UNLOCK_PROFILER ();
+                       LOG_WRITER_THREAD ("data_writer_thread: flushed buffers and released lock");
                }
                
                if (profiler->terminate_writer_thread) {
@@ -5778,6 +5949,13 @@ mono_profiler_startup (const char *desc)
        LOG_WRITER_THREAD ("mono_profiler_startup: creating writer thread");
        CREATE_WRITER_THREAD (data_writer_thread);
        LOG_WRITER_THREAD ("mono_profiler_startup: created writer thread");
+       if ((profiler->command_port >= 1024) && (profiler->command_port <= 65535)) {
+               LOG_USER_THREAD ("mono_profiler_startup: creating user thread");
+               CREATE_USER_THREAD (user_thread);
+               LOG_USER_THREAD ("mono_profiler_startup: created user thread");
+       } else {
+               LOG_USER_THREAD ("mono_profiler_startup: skipping user thread creation");
+       }
 
        ALLOCATE_PROFILER_THREAD_DATA ();
        
index 3aec6cd04bfeb15795e75fbba389aa841ee87f50..30d435cde0ac7c93edb907063b238e705cbb6917 100644 (file)
@@ -1,3 +1,7 @@
+2009-08-12 Rodrigo Kumpera  <rkumpera@novell.com>
+
+       * bug-528055.il: Regression test for #528055.
+
 2009-08-04  Atsushi Enomoto  <atsushi@ximian.com>
 
        * make_imt_test.sh: fix freebsd build by Makoto Kishimoto
index ae44aac94ff0d99e67f6df5784aebb2b6cd9ff1a..be4e205d4d59df2a9c8e0db309f595a3fe9d2871 100644 (file)
@@ -457,6 +457,7 @@ TEST_IL_SRC=                        \
        bug445361.il    \
        bug-463303.il   \
        bug469742.2.il  \
+       bug-528055.il   \
        bug-481403.il
 
 #      bug-318677.il
diff --git a/mono/tests/bug-528055.il b/mono/tests/bug-528055.il
new file mode 100644 (file)
index 0000000..43854db
--- /dev/null
@@ -0,0 +1,103 @@
+.assembly extern mscorlib
+{
+  .ver 2:0:0:0
+  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )
+}
+.assembly 'simple_assembly'
+{
+  .hash algorithm 0x00008004
+  .ver  0:0:0:0
+}
+
+.module simple_assembly.exe
+
+.class sealed public auto ansi beforefieldinit Generic`1<T> 
+{
+       .method public hidebysig  specialname rtspecialname instance default void '.ctor' ()
+       {
+               .maxstack 8
+               ldarg.0 
+               call instance void object::'.ctor'()
+               ret 
+       }
+
+       .field public !T a
+       .field public int32 a
+}
+
+
+.class sealed public auto ansi beforefieldinit Regular 
+{
+       .method public hidebysig  specialname rtspecialname instance default void '.ctor' ()
+       {
+               .maxstack 8
+               ldarg.0 
+               call instance void object::'.ctor'()
+               ret 
+       }
+
+       .field public float32 a
+       .field public int32 a
+}
+
+.class public auto ansi beforefieldinit Program
+{
+       .method public static int32 Main () cil managed 
+       {
+               .entrypoint
+               .maxstack 8
+               .locals init (class Generic`1<float32> V_0, class Regular       V_1)    
+
+               newobj instance void class Generic`1<float32>::'.ctor'()
+               stloc.0 
+               ldloc.0 
+               ldc.r4 2.
+               stfld !0 class Generic`1<float32>::a
+               ldloc.0 
+               ldc.i4.s 0x0a
+               stfld int32 class Generic`1<float32>::a
+               ldloc.0 
+               ldfld !0 class Generic`1<float32>::a
+               ldc.r4 2.
+               beq TEST_2
+
+               ldc.i4.1 
+               ret
+TEST_2:
+               ldloc.0 
+               ldfld int32 class Generic`1<float32>::a
+               ldc.i4.s 0x0a
+               beq TEST_3
+
+               ldc.i4.2 
+               ret
+TEST_3:
+               newobj instance void class Regular::'.ctor'()
+               stloc.1 
+               ldloc.1 
+               ldc.r4 2.
+               stfld float32 Regular::a
+               ldloc.1 
+               ldc.i4.s 0x0a
+               stfld int32 Regular::a
+               ldloc.1 
+               ldfld float32 Regular::a
+               ldc.r4 2.
+               beq TEST_4
+
+               ldc.i4.3 
+               ret
+TEST_4:
+               ldloc.1
+               ldfld int32 Regular::a
+               ldc.i4.s 0x0a
+               beq GOOD
+
+               ldc.i4.4 
+               ret 
+GOOD:
+               ldc.i4.0 
+               ret     
+       }
+}
+
index 0121e37283a1d8031c53d5ccb94492dce2bf145f..7d03b185022f79402ba5e5796eeafcf2fb1a1900 100644 (file)
@@ -1,3 +1,13 @@
+2009-08-17 Rodrigo Kumpera  <rkumpera@novell.com>
+
+       * valid_generic_type_definition_on_boxing_position.cs: Valid encoding of GTD on
+       box position.
+
+2009-08-14 Rodrigo Kumpera  <rkumpera@novell.com>
+
+       *unverifiable_ldobj_with_generic_type_definition.il: Regression test for
+       bug #531237.
+
 2009-07-20 Rodrigo Kumpera  <rkumpera@novell.com>
 
        * Makefile: Add support for new test kind badmd for tests with broken
diff --git a/mono/tests/verifier/unverifiable_ldobj_with_generic_type_definition.il b/mono/tests/verifier/unverifiable_ldobj_with_generic_type_definition.il
new file mode 100644 (file)
index 0000000..5b25e25
--- /dev/null
@@ -0,0 +1,98 @@
+\r
+//  Microsoft (R) .NET Framework IL Disassembler.  Version 2.0.50727.42\r
+//  Copyright (c) Microsoft Corporation.  All rights reserved.\r
+\r
+\r
+\r
+// Metadata version: v2.0.50727\r
+.assembly extern mscorlib\r
+{\r
+  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\V.4..\r
+  .ver 2:0:0:0\r
+}\r
+.assembly 'bug-new'\r
+{\r
+  .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx\r
+                                                                                                             63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.\r
+  .hash algorithm 0x00008004\r
+  .ver 0:0:0:0\r
+}\r
+.module 'bug-new.exe'\r
+// MVID: {6822252F-C77F-4A9B-9396-C53036CCD72E}\r
+.imagebase 0x00400000\r
+.file alignment 0x00000200\r
+.stackreserve 0x00100000\r
+.subsystem 0x0003       // WINDOWS_CUI\r
+.corflags 0x00000001    //  ILONLY\r
+// Image base: 0x02E80000\r
+\r
+\r
+// =============== CLASS MEMBERS DECLARATION ===================\r
+\r
+.class private auto ansi beforefieldinit G`1<T>\r
+       extends [mscorlib]System.Object\r
+{\r
+  .class sequential ansi sealed nested public beforefieldinit S<T>\r
+         extends [mscorlib]System.ValueType\r
+  {\r
+    .pack 0\r
+    .size 1\r
+    .method public hidebysig instance void \r
+            Test() cil managed\r
+    {\r
+      // Code size       22 (0x16)\r
+      .maxstack  8\r
+      IL_0000:  ldarg.0\r
+      IL_0001:  ldobj      G`1/S\r
+      IL_0006:  box        G`1/S\r
+      IL_000b:  call       instance class [mscorlib]System.Type [mscorlib]System.Object::GetType()\r
+      IL_0010:  call       void [mscorlib]System.Console::WriteLine(object)\r
+      IL_0015:  ret\r
+    } // end of method S::Test\r
+\r
+  } // end of class S\r
+\r
+  .method public hidebysig specialname rtspecialname \r
+          instance void  .ctor() cil managed\r
+  {\r
+    // Code size       7 (0x7)\r
+    .maxstack  8\r
+    IL_0000:  ldarg.0\r
+    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\r
+    IL_0006:  ret\r
+  } // end of method G`1::.ctor\r
+\r
+} // end of class G`1\r
+\r
+.class private auto ansi beforefieldinit C\r
+       extends [mscorlib]System.Object\r
+{\r
+  .method public hidebysig specialname rtspecialname \r
+          instance void  .ctor() cil managed\r
+  {\r
+    // Code size       7 (0x7)\r
+    .maxstack  8\r
+    IL_0000:  ldarg.0\r
+    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\r
+    IL_0006:  ret\r
+  } // end of method C::.ctor\r
+\r
+  .method public hidebysig static void  Main() cil managed\r
+  {\r
+    .entrypoint\r
+    // Code size       16 (0x10)\r
+    .maxstack  2\r
+    .locals init (valuetype G`1/S<int32> V_0)\r
+    IL_0000:  ldloca.s   V_0\r
+    IL_0002:  initobj    valuetype G`1/S<int32>\r
+    IL_0008:  ldloca.s   V_0\r
+    IL_000a:  call       instance void valuetype G`1/S<int32>::Test()\r
+    IL_000f:  ret\r
+  } // end of method C::Main\r
+\r
+} // end of class C\r
+\r
+\r
+// =============================================================\r
+\r
+// *********** DISASSEMBLY COMPLETE ***********************\r
diff --git a/mono/tests/verifier/valid_generic_type_definition_on_boxing_position.cs b/mono/tests/verifier/valid_generic_type_definition_on_boxing_position.cs
new file mode 100644 (file)
index 0000000..f527a88
--- /dev/null
@@ -0,0 +1,28 @@
+using System;
+
+public class Bar<T> {
+       public int Z {get;set;}
+}
+
+public class Foo<T> {
+       public T Test {get;set;}
+       public int Z (Bar<T> t) {
+               return t.Z;
+       }
+}
+
+public struct Cat<T> {
+       T t;
+       public void Test () {
+               Console.WriteLine (GetType ());
+       }
+}
+
+
+class Driver {
+       static void Main () {
+               Cat<int> c = new Cat<int> ();
+               c.Test ();
+               new Foo<double> ().Z(new Bar<double>());
+       }
+}
\ No newline at end of file
index 5808bb53e5c9d73abc5550729890238de7c36297..5a758a88eef3facb1bc976421cb5cf698eb445db 100644 (file)
@@ -1,3 +1,21 @@
+2009-08-18  Christian Hergert  <chris@dronelabs.com>
+
+       * strtod.c: Fix warnings for uninitialized variables.
+
+2009-08-18  Christian Hergert  <chris@dronelabs.com>
+
+       * mono-proclib.c:
+       * mono-counters.c: Fix printf warnings.
+
+2009-08-12  Mark Probst  <mark.probst@gmail.com>
+
+       * mono-hash.c (mono_g_hash_mark): If the keys are managed objects,
+       rehash the table after marking.
+
+2009-08-10 Gonzalo Paniagua Javier <gonzalo@novell.com>
+
+       * monobitset.h: add comment.
+
 2009-08-01  Zoltan Varga  <vargaz@gmail.com>
 
        * mono-sigcontext.h (UCONTEXT_GREGS): Fix freebsd definition.
index 15036e5c113dd8bf098a7e42cf34137cd48f1924..af77254c9bdae864b9ed6c79c046503fc448d95e 100644 (file)
@@ -105,14 +105,14 @@ dump_counter (MonoCounter *counter, FILE *outfile) {
                      int64val = ((LongFunc)counter->addr) ();
              else
                      int64val = *(gint64*)counter->addr;
-             fprintf (outfile, ENTRY_FMT "%lld\n", counter->name, int64val);
+             fprintf (outfile, ENTRY_FMT "%lld\n", counter->name, (long long)int64val);
              break;
        case MONO_COUNTER_ULONG:
              if (counter->type & MONO_COUNTER_CALLBACK)
                      uint64val = ((ULongFunc)counter->addr) ();
              else
                      uint64val = *(guint64*)counter->addr;
-             fprintf (outfile, ENTRY_FMT "%llu\n", counter->name, uint64val);
+             fprintf (outfile, ENTRY_FMT "%llu\n", counter->name, (unsigned long long)uint64val);
              break;
        case MONO_COUNTER_WORD:
              if (counter->type & MONO_COUNTER_CALLBACK)
@@ -122,7 +122,7 @@ dump_counter (MonoCounter *counter, FILE *outfile) {
 #if SIZEOF_VOID_P == 8
              fprintf (outfile, ENTRY_FMT "%lld\n", counter->name, (gint64)wordval);
 #else
-             fprintf (outfile, ENTRY_FMT "%d\n", counter->name, wordval);
+             fprintf (outfile, ENTRY_FMT "%d\n", counter->name, (gint)wordval);
 #endif
              break;
        case MONO_COUNTER_DOUBLE:
index 55d8adf05834f3ccab1a0fd323331e1bb27b9f53..5eabf3aac58eae5f749434da9f7cf16951957677 100644 (file)
@@ -910,6 +910,9 @@ mono_g_hash_mark (void *addr, MonoGCCopyFunc mark_func)
                        }
                }
        }
+
+       if (table->gc_type == MONO_HASH_KEY_GC || table->gc_type == MONO_HASH_KEY_VALUE_GC)
+               g_hash_table_resize (table);
 }
 
 #endif
index 266c6c3fbd4ee18cc3b66d605559c11eb3a66d2a..fa5f293814b5ed6168286140e2740f628d9a475e 100644 (file)
@@ -157,7 +157,6 @@ mono_process_get_name (gpointer pid, char *buf, int len)
 #if USE_SYSCTL
        int mib [4];
        int res;
-       char *p;
        size_t data_len = sizeof (struct kinfo_proc);
        struct kinfo_proc processi;
 
index 8dac35b50d36d9ebe89a8dcfd8a993a5dca4982e..7ec53f60bcf91cf53c3ea6f87f77589f7b09fe4f 100644 (file)
@@ -3,6 +3,11 @@
 
 #include <glib.h>
 
+/*
+ * When embedding, you have to define MONO_ZERO_LEN_ARRAY before including any
+ * other Mono header file if you use a different compiler from the one used to
+ * build Mono.
+ */
 #ifndef MONO_ZERO_LEN_ARRAY
 #ifdef __GNUC__
 #define MONO_ZERO_LEN_ARRAY 0
index 76840194276682ceee8553fff3bd4860f3e9d548..f20c28f9c382e9f5cc1d10cfbcd65c241d69a51b 100644 (file)
@@ -1561,7 +1561,7 @@ mono_strtod
        double aadj, aadj1, adj, rv, rv0;
        Long L;
        ULong y, z;
-       Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
+       Bigint *bb = NULL, *bb1, *bd = NULL, *bd0, *bs = NULL, *delta = NULL;
 #ifdef SET_INEXACT
        int inexact, oldinexact;
 #endif
index 2b2559291f1dc939df75e72a74e34471d9852be8..5fbde483e4ba5a03ec65e95f1943c54ed2b7d05f 100644 (file)
@@ -35,7 +35,7 @@ bin_SCRIPTS = \
        $(scripts_rpmhelpers)   \
        $(MDOC_SUBCOMMANDS)     \
        $(MDOC_COMPAT)          \
-       mod                     \
+       mod$(SCRIPT_SUFFIX)     \
        mono-test-install
 
 if INSTALL_4_0
@@ -212,6 +212,7 @@ nunit-console2$(SCRIPT_SUFFIX): $(SCRIPT_IN) Makefile
        $(REWRITE2_DEBUG) -e 's,@''exe_name@,nunit-console,g' $(srcdir)/$(SCRIPT_IN) | $(FILTER) > $@.tmp
        mv $@.tmp $@
 
+#FIXME: this is not the correct rule for mod.bat.
 mod$(SCRIPT_SUFFIX): mod.in Makefile
        $(REWRITE1) -e "s,@""exe_name@,mod,g" $(srcdir)/mod.in > $@.tmp
        mv $@.tmp $@
@@ -220,6 +221,7 @@ $(scripts_1_0): $(SCRIPT_IN) Makefile
        $(REWRITE1) -e 's,@''exe_name@,$@,g' $(srcdir)/$(SCRIPT_IN) | $(FILTER) > $@.tmp
        mv $@.tmp $@
 
+#FIXME: this is not the correct rule for bat files.
 $(scripts_1_0_umask): script_umask.in Makefile
        $(REWRITE1) -e 's,@''exe_name@,$@,g' $(srcdir)/script_umask.in > $@.tmp
        mv $@.tmp $@
index 88d769de32304af24150b8343087b4c239288b65..62f8cfd62753720406f5558641b298ae256d3a5c 100644 (file)
 #define MONO_XEN_OPT 1
 
 /* Length of zero length arrays */
-/* #undef MONO_ZERO_ARRAY_LENGTH */
+#define MONO_ZERO_LEN_ARRAY 1
 
 /* Name of /dev/random */
 #define NAME_DEV_RANDOM ""