Index: src/Boo.Lang.Compiler/Steps/EmitAssembly.cs =================================================================== --- src/Boo.Lang.Compiler/Steps/EmitAssembly.cs (revision 1959) +++ src/Boo.Lang.Compiler/Steps/EmitAssembly.cs (working copy) @@ -36,6 +36,7 @@ using System.Reflection.Emit; using System.Text; using System.Text.RegularExpressions; +using Boo.Lang; using Boo.Lang.Runtime; using Boo.Lang.Compiler.Ast; using Boo.Lang.Compiler; @@ -98,7 +99,7 @@ ModuleBuilder _moduleBuilder; - ISymbolDocumentWriter _symbolDocWriter; + Hash _symbolDocWriters = new Hash(); // IL generation state ILGenerator _il; @@ -384,7 +385,8 @@ _asmBuilder = null; _moduleBuilder = null; - _symbolDocWriter = null; + _symbolDocWriters.Clear(); + _symbolDocWriters = null; _il = null; _returnValueLocal = null; _returnType = null; @@ -405,6 +407,7 @@ { InitializeDebugInfoWriter(module); Visit(module.Members); + _symbolDocWriters.Clear(); } private void InitializeDebugInfoWriter(Module module) @@ -413,16 +416,12 @@ string fname = module.LexicalInfo.FileName; if (null != fname) { - _symbolDocWriter = _moduleBuilder.DefineDocument( + _symbolDocWriters[fname] = _moduleBuilder.DefineDocument( fname, Guid.Empty, Guid.Empty, SymDocumentType.Text); } - else - { - _symbolDocWriter = null; - } } override public void OnEnumDefinition(EnumDefinition node) @@ -1024,21 +1023,21 @@ switch (node.Operator) { case UnaryOperatorType.LogicalNot: - { - EmitLogicalNot(node); + { + EmitLogicalNot(node); break; } case UnaryOperatorType.UnaryNegation: - { - EmitUnaryNegation(node); + { + EmitUnaryNegation(node); break; } - case UnaryOperatorType.OnesComplement: - { - EmitOnesComplement(node); - break; + case UnaryOperatorType.OnesComplement: + { + EmitOnesComplement(node); + break; } default: @@ -1047,16 +1046,16 @@ break; } } - } - - private void EmitOnesComplement(UnaryExpression node) - { + } + + private void EmitOnesComplement(UnaryExpression node) + { node.Operand.Accept(this); - _il.Emit(OpCodes.Not); - } - - private void EmitLogicalNot(UnaryExpression node) - { + _il.Emit(OpCodes.Not); + } + + private void EmitLogicalNot(UnaryExpression node) + { node.Operand.Accept(this); IType typeOnStack = PopType(); if (IsBoolOrInt(typeOnStack) || EmitToBoolIfNeeded(typeOnStack)) @@ -1067,19 +1066,19 @@ { EmitGenericNot(); } - PushBool(); - } - - private void EmitUnaryNegation(UnaryExpression node) - { + PushBool(); + } + + private void EmitUnaryNegation(UnaryExpression node) + { node.Operand.Accept(this); IType type = PopType(); _il.Emit(OpCodes.Ldc_I4, -1); EmitCastIfNeeded(type, TypeSystemServices.IntType); _il.Emit(OpCodes.Mul); - PushType(type); - } - + PushType(type); + } + bool ShouldLeaveValueOnStack(Expression node) { return node.ParentNode.NodeType != NodeType.ExpressionStatement; @@ -1637,18 +1636,18 @@ void InvokeRegularMethod(IMethod method, MethodInfo mi, MethodInvocationExpression node) { if (!mi.IsStatic) - { - PushTargetObject(node, mi); + { + PushTargetObject(node, mi); } PushArguments(method, node.Arguments); _il.EmitCall(GetCallOpCode(node, method, mi), mi, null); PushType(method.ReturnType); - } - - private void PushTargetObject(MethodInvocationExpression node, MethodInfo mi) - { + } + + private void PushTargetObject(MethodInvocationExpression node, MethodInfo mi) + { Expression target = GetTargetObject(node); IType targetType = target.ExpressionType; if (targetType.IsValueType) @@ -1668,28 +1667,28 @@ // pushes target reference Visit(node.Target); PopType(); - } - } - - private static Expression GetTargetObject(MethodInvocationExpression node) - { - return ((MemberReferenceExpression)node.Target).Target; - } - - private OpCode GetCallOpCode(MethodInvocationExpression node, IMethod method, MethodInfo mi) - { - if (method.IsStatic) return OpCodes.Call; - if (NodeType.SuperLiteralExpression == GetTargetObject(node).NodeType) return OpCodes.Call; - if (IsValueTypeMethodCall(node, method)) return OpCodes.Call; - return OpCodes.Callvirt; - } - - private bool IsValueTypeMethodCall(MethodInvocationExpression node, IMethod method) - { - IType type = GetTargetObject(node).ExpressionType; - return type.IsValueType && method.DeclaringType == type; - } - + } + } + + private static Expression GetTargetObject(MethodInvocationExpression node) + { + return ((MemberReferenceExpression)node.Target).Target; + } + + private OpCode GetCallOpCode(MethodInvocationExpression node, IMethod method, MethodInfo mi) + { + if (method.IsStatic) return OpCodes.Call; + if (NodeType.SuperLiteralExpression == GetTargetObject(node).NodeType) return OpCodes.Call; + if (IsValueTypeMethodCall(node, method)) return OpCodes.Call; + return OpCodes.Callvirt; + } + + private bool IsValueTypeMethodCall(MethodInvocationExpression node, IMethod method) + { + IType type = GetTargetObject(node).ExpressionType; + return type.IsValueType && method.DeclaringType == type; + } + void InvokeSuperMethod(IMethod methodInfo, MethodInvocationExpression node) { IMethod super = ((InternalMethod)methodInfo).Overriden; @@ -1849,6 +1848,8 @@ override public void OnTimeSpanLiteralExpression(TimeSpanLiteralExpression node) { + Warnings.Add(CompilerWarningFactory.CustomWarning(node.LexicalInfo, + "TimeSpanLiteralExpression is deprecated")); _il.Emit(OpCodes.Ldc_I8, node.Value.Ticks); _il.Emit(OpCodes.Newobj, TimeSpan_LongConstructor); PushType(TypeSystemServices.TimeSpanType); @@ -2598,9 +2599,19 @@ LexicalInfo start = startNode.LexicalInfo; if (start.IsValid) { + ISymbolDocumentWriter symbolWriter = (ISymbolDocumentWriter)_symbolDocWriters[start.FileName]; + if (symbolWriter == null) + { + symbolWriter = _moduleBuilder.DefineDocument( + start.FileName, + Guid.Empty, + Guid.Empty, + SymDocumentType.Text); + _symbolDocWriters[start.FileName] = symbolWriter; + } try { - _il.MarkSequencePoint(_symbolDocWriter, start.Line, 0, start.Line+1, 0); + _il.MarkSequencePoint(symbolWriter, start.Line, 0, start.Line+1, 0); } catch (Exception x) { @@ -2611,7 +2622,7 @@ private bool CanEmitDebugInfo() { - return null != _symbolDocWriter; + return _symbolDocWriters.Count > 0; } bool IsBoolOrInt(IType type) @@ -2888,6 +2899,12 @@ if (!expectedType.IsAssignableFrom(actualType)) { + IMethod method = TypeSystemServices.GetImplicitConversionMethod(expectedType, actualType); + if (method != null) + { + _il.EmitCall(OpCodes.Call, GetMethodInfo(method), null); + return; + } if (expectedType.IsValueType) { if (actualType.IsValueType) @@ -3396,6 +3413,10 @@ { attributes |= TypeAttributes.Sealed; } + if (type.IsStatic) + { + attributes |= TypeAttributes.Abstract | TypeAttributes.Sealed; + } if (((IType)type.Entity).IsValueType) { attributes |= TypeAttributes.SequentialLayout; @@ -3460,6 +3481,10 @@ if (member.IsStatic) { attributes |= MethodAttributes.Static; + if (member.Name.StartsWith("op_")) + { + attributes |= MethodAttributes.SpecialName; + } } if (member.IsFinal) {