Index: src/Boo.Lang.Compiler/Boo.Lang.Compiler.csproj
===================================================================
--- src/Boo.Lang.Compiler/Boo.Lang.Compiler.csproj (revision 2352)
+++ src/Boo.Lang.Compiler/Boo.Lang.Compiler.csproj (working copy)
@@ -19,11 +19,11 @@
..\boo.snk
False
File
+ false
false
4
- false
false
false
false
@@ -34,7 +34,6 @@
false
4
- false
true
false
false
@@ -412,7 +411,7 @@
-
+
@@ -445,7 +444,8 @@
-
+
+
Index: src/Boo.Lang.Compiler/Steps/EmitAssembly.cs
===================================================================
--- src/Boo.Lang.Compiler/Steps/EmitAssembly.cs (revision 2352)
+++ src/Boo.Lang.Compiler/Steps/EmitAssembly.cs (working copy)
@@ -1,2582 +1,2582 @@
-#region license
-// Copyright (c) 2004, Rodrigo B. de Oliveira (rbo@acm.org)
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without modification,
-// are permitted provided that the following conditions are met:
-//
-// * Redistributions of source code must retain the above copyright notice,
-// this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above copyright notice,
-// this list of conditions and the following disclaimer in the documentation
-// and/or other materials provided with the distribution.
-// * Neither the name of Rodrigo B. de Oliveira nor the names of its
-// contributors may be used to endorse or promote products derived from this
-// software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#endregion
-
-using System;
-using System.Collections;
-using System.Diagnostics;
-using System.Diagnostics.SymbolStore;
-using System.IO;
-using System.Reflection;
-using System.Reflection.Emit;
-using System.Resources;
-using System.Text;
-using System.Text.RegularExpressions;
-using System.Threading;
-using Boo.Lang.Compiler.Ast;
-using Boo.Lang.Compiler.TypeSystem;
-using Boo.Lang.Runtime;
-using Attribute = Boo.Lang.Compiler.Ast.Attribute;
-using Module = Boo.Lang.Compiler.Ast.Module;
-
-namespace Boo.Lang.Compiler.Steps
-{
- class LoopInfo
- {
- public Label BreakLabel;
-
- public Label ContinueLabel;
-
- public int TryBlockDepth;
-
- public LoopInfo(Label breakLabel, Label continueLabel, int tryBlockDepth)
- {
- BreakLabel = breakLabel;
- ContinueLabel = continueLabel;
- TryBlockDepth = tryBlockDepth;
- }
- }
-
- public class EmitAssembly : AbstractVisitorCompilerStep
- {
- static ConstructorInfo DebuggableAttribute_Constructor = typeof(DebuggableAttribute).GetConstructor(new Type[] { Types.Bool, Types.Bool });
-
- static ConstructorInfo DuckTypedAttribute_Constructor = Types.DuckTypedAttribute.GetConstructor(new Type[0]);
-
- static ConstructorInfo ParamArrayAttribute_Constructor = Types.ParamArrayAttribute.GetConstructor(new Type[0]);
-
- static MethodInfo RuntimeServices_NormalizeArrayIndex = Types.RuntimeServices.GetMethod("NormalizeArrayIndex");
-
- static MethodInfo RuntimeServices_ToBool_Object = Types.RuntimeServices.GetMethod("ToBool", new Type[] { Types.Object });
-
- static MethodInfo RuntimeServices_ToBool_Decimal = Types.RuntimeServices.GetMethod("ToBool", new Type[] { Types.Decimal });
-
- static MethodInfo Builtins_ArrayTypedConstructor = Types.Builtins.GetMethod("array", new Type[] { Types.Type, Types.Int });
-
- static MethodInfo Builtins_ArrayTypedCollectionConstructor = Types.Builtins.GetMethod("array", new Type[] { Types.Type, Types.ICollection });
-
- static MethodInfo Math_Pow = typeof(Math).GetMethod("Pow");
-
- static ConstructorInfo List_EmptyConstructor = Types.List.GetConstructor(Type.EmptyTypes);
-
- static ConstructorInfo List_ArrayBoolConstructor = Types.List.GetConstructor(new Type[] { Types.ObjectArray, Types.Bool });
-
- static ConstructorInfo Hash_Constructor = Types.Hash.GetConstructor(new Type[0]);
-
- static ConstructorInfo Regex_Constructor = typeof(Regex).GetConstructor(new Type[] { Types.String });
-
- static MethodInfo Hash_Add = Types.Hash.GetMethod("Add", new Type[] { typeof(object), typeof(object) });
-
- static ConstructorInfo TimeSpan_LongConstructor = Types.TimeSpan.GetConstructor(new Type[] { typeof(long) });
-
- static MethodInfo Type_GetTypeFromHandle = Types.Type.GetMethod("GetTypeFromHandle");
-
- AssemblyBuilder _asmBuilder;
-
- ModuleBuilder _moduleBuilder;
-
- Hashtable _symbolDocWriters = new Hashtable();
-
- // IL generation state
- ILGenerator _il;
- Label _returnLabel; // current label for method return
- LocalBuilder _returnValueLocal; // returnValueLocal
- IType _returnType;
- int _tryBlock; // are we in a try block?
- bool _checked = true;
- bool _rawArrayIndexing = false;
- Hashtable _typeCache = new Hashtable();
-
- // keeps track of types on the IL stack
- Stack _types = new Stack();
-
- Stack _loopInfoStack = new Stack();
-
- AttributeCollection _assemblyAttributes = new AttributeCollection();
-
- LoopInfo _currentLoopInfo;
-
- void EnterLoop(Label breakLabel, Label continueLabel)
- {
- _loopInfoStack.Push(_currentLoopInfo);
- _currentLoopInfo = new LoopInfo(breakLabel, continueLabel, _tryBlock);
- }
-
- bool InTryInLoop()
- {
- return _tryBlock > _currentLoopInfo.TryBlockDepth;
- }
-
- void LeaveLoop()
- {
- _currentLoopInfo = (LoopInfo)_loopInfoStack.Pop();
- }
-
- void PushType(IType type)
- {
- _types.Push(type);
- }
-
- void PushBool()
- {
- PushType(TypeSystemServices.BoolType);
- }
-
- void PushVoid()
- {
- PushType(TypeSystemServices.VoidType);
- }
-
- IType PopType()
- {
- return (IType)_types.Pop();
- }
-
- IType PeekTypeOnStack()
- {
- return (IType)_types.Peek();
- }
-
- void AssertStackIsEmpty(string message)
- {
- if (0 != _types.Count)
- {
- throw new ApplicationException(
- string.Format("{0}: {1} items still on the stack.", message, _types.Count)
- );
- }
- }
-
- override public void Run()
- {
- if (Errors.Count > 0)
- {
- return;
- }
-
- GatherAssemblyAttributes();
- SetUpAssembly();
-
- DefineTypes();
-
- DefineResources();
- DefineAssemblyAttributes();
- DefineEntryPoint();
- }
-
- void GatherAssemblyAttributes()
- {
- foreach (Module module in CompileUnit.Modules)
- {
- foreach (Attribute attribute in module.AssemblyAttributes)
- {
- _assemblyAttributes.Add(attribute);
- }
- }
- }
-
- void DefineTypes()
- {
- if (CompileUnit.Modules.Count > 0)
- {
- List types = CollectTypes();
-
- foreach (TypeDefinition type in types)
- {
- DefineType(type);
- }
-
- foreach (TypeDefinition type in types)
- {
- DefineTypeMembers(type);
- }
-
- foreach (Module module in CompileUnit.Modules)
- {
- OnModule(module);
- }
-
- EmitAttributes();
- CreateTypes(types);
- }
- }
-
- class AttributeEmitVisitor : DepthFirstVisitor
- {
- EmitAssembly _emitter;
-
- public AttributeEmitVisitor(EmitAssembly emitter)
- {
- _emitter = emitter;
- }
-
- public override void OnField(Field node)
- {
- _emitter.EmitFieldAttributes(node);
- }
-
- public override void OnEnumMember(EnumMember node)
- {
- _emitter.EmitFieldAttributes(node);
- }
-
- public override void OnEvent(Event node)
- {
- _emitter.EmitEventAttributes(node);
- }
-
- public override void OnProperty(Property node)
- {
- Visit(node.Getter);
- Visit(node.Setter);
- _emitter.EmitPropertyAttributes(node);
- }
-
- public override void OnConstructor(Constructor node)
- {
- Visit(node.Parameters);
- _emitter.EmitConstructorAttributes(node);
- }
-
- public override void OnMethod(Method node)
- {
- Visit(node.Parameters);
- _emitter.EmitMethodAttributes(node);
- }
-
- public override void OnParameterDeclaration(ParameterDeclaration node)
- {
- _emitter.EmitParameterAttributes(node);
- }
-
- public override void LeaveClassDefinition(ClassDefinition node)
- {
- _emitter.EmitTypeAttributes(node);
- }
-
- public override void LeaveInterfaceDefinition(InterfaceDefinition node)
- {
- _emitter.EmitTypeAttributes(node);
- }
-
- public override void LeaveEnumDefinition(EnumDefinition node)
- {
- _emitter.EmitTypeAttributes(node);
- }
- }
-
- delegate void CustomAttributeSetter(CustomAttributeBuilder attribute);
-
- void EmitAttributes(INodeWithAttributes node, CustomAttributeSetter setCustomAttribute)
- {
- foreach (Attribute attribute in node.Attributes)
- {
- setCustomAttribute(GetCustomAttributeBuilder(attribute));
- }
- }
-
- void EmitPropertyAttributes(Property node)
- {
- PropertyBuilder builder = GetPropertyBuilder(node);
- EmitAttributes(node, new CustomAttributeSetter(builder.SetCustomAttribute));
- }
-
- void EmitParameterAttributes(ParameterDeclaration node)
- {
- ParameterBuilder builder = (ParameterBuilder)GetBuilder(node);
- EmitAttributes(node, new CustomAttributeSetter(builder.SetCustomAttribute));
- }
-
- void EmitEventAttributes(Event node)
- {
- EventBuilder builder = (EventBuilder)GetBuilder(node);
- EmitAttributes(node, new CustomAttributeSetter(builder.SetCustomAttribute));
- }
-
- void EmitConstructorAttributes(Constructor node)
- {
- ConstructorBuilder builder = (ConstructorBuilder)GetBuilder(node);
- EmitAttributes(node, new CustomAttributeSetter(builder.SetCustomAttribute));
- }
-
- void EmitMethodAttributes(Method node)
- {
- MethodBuilder builder = GetMethodBuilder(node);
- EmitAttributes(node, new CustomAttributeSetter(builder.SetCustomAttribute));
- }
-
- void EmitTypeAttributes(TypeDefinition node)
- {
- TypeBuilder builder = GetTypeBuilder(node);
- EmitAttributes(node, new CustomAttributeSetter(builder.SetCustomAttribute));
- }
-
- void EmitFieldAttributes(TypeMember node)
- {
- FieldBuilder builder = GetFieldBuilder(node);
- EmitAttributes(node, new CustomAttributeSetter(builder.SetCustomAttribute));
- }
-
- void EmitAttributes()
- {
- AttributeEmitVisitor visitor = new AttributeEmitVisitor(this);
- foreach (Module module in CompileUnit.Modules)
- {
- module.Accept(visitor);
- }
- }
-
- void CreateTypes(List types)
- {
- new TypeCreator(this, types).Run();
- }
-
- ///
- /// Ensures that all types are created in the correct order.
- ///
- class TypeCreator
- {
- EmitAssembly _emitter;
-
- Hashtable _created;
-
- List _types;
-
- TypeMember _current;
-
- public TypeCreator(EmitAssembly emitter, List types)
- {
- _emitter = emitter;
- _types = types;
- _created = new Hashtable();
- }
-
- public void Run()
- {
- ResolveEventHandler resolveHandler = new ResolveEventHandler(OnTypeResolve);
- AppDomain current = Thread.GetDomain();
-
- try
- {
- current.TypeResolve += resolveHandler;
- CreateTypes();
- }
- finally
- {
- current.TypeResolve -= resolveHandler;
- }
- }
-
- void CreateTypes()
- {
- foreach (TypeMember type in _types)
- {
- CreateType(type);
- }
- }
-
- void CreateType(TypeMember type)
- {
- if (!_created.ContainsKey(type))
- {
- TypeMember saved = _current;
- _current = type;
-
- _created.Add(type, type);
-
- Trace("creating type '{0}'", type);
-
- if (IsNestedType(type))
- {
- CreateType((TypeMember)type.ParentNode);
- }
-
- TypeDefinition typedef = type as TypeDefinition;
- if (null != typedef)
- {
- foreach (TypeReference baseTypeRef in typedef.BaseTypes)
- {
- AbstractInternalType tag = _emitter.GetType(baseTypeRef) as AbstractInternalType;
- if (null != tag)
- {
- CreateType(tag.TypeDefinition);
- }
- }
- }
-
- ((AbstractInternalType)type.Entity).GeneratedType = _emitter.GetTypeBuilder(type).CreateType();
-
- Trace("type '{0}' successfully created", type);
-
- _current = saved;
- }
- }
-
- bool IsNestedType(TypeMember type)
- {
- NodeType parent = type.ParentNode.NodeType;
- return (NodeType.ClassDefinition == parent) ||
- (NodeType.InterfaceDefinition == parent);
- }
-
- Assembly OnTypeResolve(object sender, ResolveEventArgs args)
- {
- Trace("OnTypeResolve('{0}') during '{1}' creation.", args.Name, _current);
-
- // TypeResolve is generated whenever a type
- // contains fields of a value type not created yet.
- // All we need to do is look for value type fields
- // and create them all.
- ClassDefinition classdef = _current as ClassDefinition;
- foreach (TypeMember member in classdef.Members)
- {
- if (NodeType.Field == member.NodeType)
- {
- AbstractInternalType type = _emitter.GetType(((Field)member).Type) as AbstractInternalType;
- if (type != null && type.IsValueType)
- {
- CreateType(type.TypeDefinition);
- }
- }
- }
-
- return _emitter._asmBuilder;
- }
-
- void Trace(string format, params object[] args)
- {
- _emitter.Context.TraceVerbose(format, args);
- }
- }
-
- List CollectTypes()
- {
- List types = new List();
- foreach (Module module in CompileUnit.Modules)
- {
- CollectTypes(types, module.Members);
- }
- return types;
- }
-
- void CollectTypes(List types, TypeMemberCollection members)
- {
- foreach (TypeMember member in members)
- {
- switch (member.NodeType)
- {
- case NodeType.InterfaceDefinition:
- case NodeType.ClassDefinition:
- {
- types.Add(member);
- CollectTypes(types, ((TypeDefinition)member).Members);
- break;
- }
- case NodeType.EnumDefinition:
- {
- types.Add(member);
- break;
- }
- }
- }
- }
-
- override public void Dispose()
- {
- base.Dispose();
-
- _asmBuilder = null;
- _moduleBuilder = null;
- _symbolDocWriters.Clear();
- _il = null;
- _returnValueLocal = null;
- _returnType = null;
- _tryBlock = 0;
- _checked = true;
- _rawArrayIndexing = false;
- _types.Clear();
- _typeCache.Clear();
- _builders.Clear();
- _assemblyAttributes.Clear();
- }
-
- override public void OnAttribute(Attribute node)
- {
- }
-
- override public void OnModule(Module module)
- {
- Visit(module.Members);
- }
-
- override public void OnEnumDefinition(EnumDefinition node)
- {
- Type baseType = typeof(int);
-
- TypeBuilder builder = GetTypeBuilder(node);
-
- builder.DefineField("value__", baseType,
- FieldAttributes.Public |
- FieldAttributes.SpecialName |
- FieldAttributes.RTSpecialName);
-
- foreach (EnumMember member in node.Members)
- {
- FieldBuilder field = builder.DefineField(member.Name, builder,
- FieldAttributes.Public |
- FieldAttributes.Static |
- FieldAttributes.Literal);
- field.SetConstant((int)member.Initializer.Value);
- SetBuilder(member, field);
- }
- }
-
- override public void OnArrayTypeReference(ArrayTypeReference node)
- {
- }
-
- override public void OnClassDefinition(ClassDefinition node)
- {
- EmitTypeDefinition(node);
- }
-
- override public void OnField(Field node)
- {
- FieldBuilder builder = GetFieldBuilder(node);
- if (builder.IsLiteral)
- {
- builder.SetConstant(GetInternalFieldStaticValue((InternalField)node.Entity));
- }
- }
-
- override public void OnInterfaceDefinition(InterfaceDefinition node)
- {
- TypeBuilder builder = GetTypeBuilder(node);
- foreach (TypeReference baseType in node.BaseTypes)
- {
- builder.AddInterfaceImplementation(GetSystemType(baseType));
- }
- }
-
- override public void OnCallableDefinition(CallableDefinition node)
- {
- NotImplemented(node, "Unexpected callable definition!");
- }
-
- void EmitTypeDefinition(TypeDefinition node)
- {
- TypeBuilder current = GetTypeBuilder(node);
- EmitBaseTypesAndAttributes(node, current);
- Visit(node.Members);
- }
-
- override public void OnMethod(Method method)
- {
- if (method.IsRuntime) return;
- if (IsPInvoke(method)) return;
-
- MethodBuilder methodBuilder = GetMethodBuilder(method);
- if (null != method.ExplicitInfo)
- {
- IMethod ifaceMethod = (IMethod)method.ExplicitInfo.Entity;
- MethodInfo ifaceInfo = GetMethodInfo(ifaceMethod);
- MethodInfo implInfo = GetMethodInfo((IMethod)method.Entity);
-
- TypeBuilder typeBuilder = GetTypeBuilder(method.DeclaringType);
- typeBuilder.DefineMethodOverride(implInfo, ifaceInfo);
- }
-
- EmitMethod(method, methodBuilder.GetILGenerator());
- }
-
- void EmitMethod(Method method, ILGenerator generator)
- {
- _il = generator;
-
- DefineLabels(method);
- Visit(method.Locals);
-
- BeginMethodBody(GetEntity(method).ReturnType);
- Visit(method.Body);
- EndMethodBody();
- }
-
- void BeginMethodBody(IType returnType)
- {
- _returnType = returnType;
- _returnLabel = _il.DefineLabel();
- if (TypeSystemServices.VoidType != _returnType)
- {
- _returnValueLocal = _il.DeclareLocal(GetSystemType(_returnType));
- }
- }
-
- void EndMethodBody()
- {
- _il.MarkLabel(_returnLabel);
- if (null != _returnValueLocal)
- {
- _il.Emit(OpCodes.Ldloc, _returnValueLocal);
- _returnValueLocal = null;
- }
- _il.Emit(OpCodes.Ret);
- }
-
- private bool IsPInvoke(Method method)
- {
- return GetEntity(method).IsPInvoke;
- }
-
- override public void OnBlock(Block block)
- {
- bool currentChecked = _checked;
- _checked = AstAnnotations.IsChecked(block);
-
- bool currentArrayIndexing = _rawArrayIndexing;
- _rawArrayIndexing = AstAnnotations.IsRawIndexing(block);
-
- Visit(block.Statements);
-
- _rawArrayIndexing = currentArrayIndexing;
- _checked = currentChecked;
- }
-
- void DefineLabels(Method method)
- {
- foreach (InternalLabel label in ((InternalMethod)method.Entity).Labels)
- {
- label.Label = _il.DefineLabel();
- }
- }
-
- override public void OnConstructor(Constructor constructor)
- {
- if (constructor.IsRuntime) return;
-
- ConstructorBuilder builder = GetConstructorBuilder(constructor);
- EmitMethod(constructor, builder.GetILGenerator());
- }
-
- override public void OnLocal(Local local)
- {
- InternalLocal info = GetInternalLocal(local);
- info.LocalBuilder = _il.DeclareLocal(GetSystemType(local));
- if (Parameters.Debug)
- {
- info.LocalBuilder.SetLocalSymInfo(local.Name);
- }
- }
-
- override public void OnForStatement(ForStatement node)
- {
- NotImplemented("ForStatement");
- }
-
- override public void OnReturnStatement(ReturnStatement node)
- {
- EmitDebugInfo(node);
- OpCode retOpCode = _tryBlock > 0 ? OpCodes.Leave : OpCodes.Br;
-
- if (null != node.Expression)
- {
- Visit(node.Expression);
- EmitCastIfNeeded(_returnType, PopType());
- _il.Emit(OpCodes.Stloc, _returnValueLocal);
- }
- _il.Emit(retOpCode, _returnLabel);
- EmitNopDebugInfo(node);
- }
-
- override public void OnRaiseStatement(RaiseStatement node)
- {
- EmitDebugInfo(node);
- if (node.Exception == null)
- {
- _il.Emit(OpCodes.Rethrow);
- }
- else
- {
- Visit(node.Exception); PopType();
- _il.Emit(OpCodes.Throw);
- }
- EmitNopDebugInfo(node);
- }
-
- private void EmitNopDebugInfo(Statement node)
- {
- // HACK: workaround - mono reports the position of
- // raise as being the position of the next instruction
- // after it
- if (EmitDebugInfo(node))
- {
- _il.Emit(OpCodes.Nop);
- }
- }
-
- override public void OnTryStatement(TryStatement node)
- {
- ++_tryBlock;
-
- _il.BeginExceptionBlock();
- Visit(node.ProtectedBlock);
- Visit(node.ExceptionHandlers);
- if (null != node.EnsureBlock)
- {
- _il.BeginFinallyBlock();
- Visit(node.EnsureBlock);
- }
- _il.EndExceptionBlock();
-
- --_tryBlock;
- }
-
- override public void OnExceptionHandler(ExceptionHandler node)
- {
- _il.BeginCatchBlock(GetSystemType(node.Declaration));
- _il.Emit(OpCodes.Stloc, GetLocalBuilder(node.Declaration));
- Visit(node.Block);
- }
-
- override public void OnUnpackStatement(UnpackStatement node)
- {
- NotImplemented("Unpacking");
- }
-
- override public bool EnterExpressionStatement(ExpressionStatement node)
- {
- EmitDebugInfo(node);
- return true;
- }
-
- override public void LeaveExpressionStatement(ExpressionStatement node)
- {
- // if the type of the inner expression is not
- // void we need to pop its return value to leave
- // the stack sane
- DiscardValueOnStack();
- AssertStackIsEmpty("stack must be empty after a statement!");
-
- EmitNopDebugInfo(node);
- }
-
- void DiscardValueOnStack()
- {
- if (PopType() != TypeSystemServices.VoidType)
- {
- _il.Emit(OpCodes.Pop);
- }
- }
-
- override public void OnUnlessStatement(UnlessStatement node)
- {
- Label endLabel = _il.DefineLabel();
- EmitDebugInfo(node);
- EmitBranchTrue(node.Condition, endLabel);
- EmitNopDebugInfo(node);
- node.Block.Accept(this);
- _il.MarkLabel(endLabel);
- }
-
- void OnSwitch(MethodInvocationExpression node)
- {
- ExpressionCollection args = node.Arguments;
- Visit(args[0]);
- EmitCastIfNeeded(TypeSystemServices.IntType, PopType());
-
- Label[] labels = new Label[args.Count-1];
- for (int i=0; i 0)
- {
- EmitObjectArray(node.Items);
- _il.Emit(OpCodes.Ldc_I4_1);
- _il.Emit(OpCodes.Newobj, List_ArrayBoolConstructor);
- }
- else
- {
- _il.Emit(OpCodes.Newobj, List_EmptyConstructor);
- }
- PushType(TypeSystemServices.ListType);
- }
-
- override public void OnArrayLiteralExpression(ArrayLiteralExpression node)
- {
- IArrayType type = (IArrayType)node.ExpressionType;
- EmitArray(type.GetElementType(), node.Items);
- PushType(type);
- }
-
- override public void OnRELiteralExpression(RELiteralExpression node)
- {
- _il.Emit(OpCodes.Ldstr, RuntimeServices.Mid(node.Value, 1, -1));
- _il.Emit(OpCodes.Newobj, Regex_Constructor);
- PushType(node.ExpressionType);
- }
-
- override public void OnStringLiteralExpression(StringLiteralExpression node)
- {
- _il.Emit(OpCodes.Ldstr, node.Value);
- PushType(TypeSystemServices.StringType);
- }
-
- override public void OnCharLiteralExpression(CharLiteralExpression node)
- {
- _il.Emit(OpCodes.Ldc_I4, node.Value[0]);
- PushType(TypeSystemServices.CharType);
- }
-
- override public void OnSlicingExpression(SlicingExpression node)
- {
- if (AstUtil.IsLhsOfAssignment(node))
- {
- return;
- }
-
- Visit(node.Target);
-
- IArrayType type = (IArrayType)PopType();
- EmitNormalizedArrayIndex(node, node.Indices[0].Begin);
-
- IType elementType = type.GetElementType();
- OpCode opcode = GetLoadEntityOpCode(elementType);
- if (OpCodes.Ldelema.Value == opcode.Value)
- {
- Type systemType = GetSystemType(elementType);
- _il.Emit(opcode, systemType);
- _il.Emit(OpCodes.Ldobj, systemType);
- }
- else
- {
- _il.Emit(opcode);
- }
- PushType(elementType);
- }
-
- void EmitNormalizedArrayIndex(SlicingExpression sourceNode, Expression index)
- {
- bool isNegative = false;
- if (CanBeNegative(index, ref isNegative)
- && !_rawArrayIndexing
- && !AstAnnotations.IsRawIndexing(sourceNode))
- {
- if (isNegative)
- {
- _il.Emit(OpCodes.Dup);
- _il.Emit(OpCodes.Ldlen);
- EmitLoadInt(index);
- _il.Emit(OpCodes.Add);
- }
- else
- {
- _il.Emit(OpCodes.Dup);
- EmitLoadInt(index);
- _il.EmitCall(OpCodes.Call, RuntimeServices_NormalizeArrayIndex, null);
- }
- }
- else
- {
- EmitLoadInt(index);
- }
- }
-
- bool CanBeNegative(Expression expression, ref bool isNegative)
- {
- IntegerLiteralExpression integer = expression as IntegerLiteralExpression;
- if (null != integer)
- {
- if (integer.Value >= 0)
- {
- return false;
- }
- isNegative = true;
- }
- return true;
- }
-
- void EmitLoadInt(Expression expression)
- {
- Visit(expression);
- EmitCastIfNeeded(TypeSystemServices.IntType, PopType());
- }
-
- override public void OnExpressionInterpolationExpression(ExpressionInterpolationExpression node)
- {
- Type stringBuilderType = typeof(StringBuilder);
- ConstructorInfo constructor = stringBuilderType.GetConstructor(new Type[0]);
- MethodInfo appendObject = stringBuilderType.GetMethod("Append", new Type[] { typeof(object) });
- MethodInfo appendString = stringBuilderType.GetMethod("Append", new Type[] { typeof(string) });
-
- _il.Emit(OpCodes.Newobj, constructor);
-
- foreach (Expression arg in node.Expressions)
- {
- Visit(arg);
-
- IType argType = PopType();
- if (TypeSystemServices.StringType == argType)
- {
- _il.EmitCall(OpCodes.Call, appendString, null);
- }
- else
- {
- EmitCastIfNeeded(TypeSystemServices.ObjectType, argType);
- _il.EmitCall(OpCodes.Call, appendObject, null);
- }
- }
- _il.EmitCall(OpCodes.Call, stringBuilderType.GetMethod("ToString", new Type[0]), null);
- PushType(TypeSystemServices.StringType);
- }
-
- void LoadMemberTarget(Expression self, IMember member)
- {
- if (member.DeclaringType.IsValueType)
- {
- LoadAddress(self);
- }
- else
- {
- Visit(self);
- PopType();
- }
- }
-
- void EmitLoadFieldAddress(Expression expression, IField field)
- {
- if (field.IsStatic)
- {
- _il.Emit(OpCodes.Ldsflda, GetFieldInfo(field));
- }
- else
- {
- LoadMemberTarget(((MemberReferenceExpression)expression).Target, field);
- _il.Emit(OpCodes.Ldflda, GetFieldInfo(field));
- }
- }
-
- void EmitLoadField(Expression self, IField fieldInfo)
- {
- if (fieldInfo.IsStatic)
- {
- if (fieldInfo.IsLiteral)
- {
- EmitLoadLiteralField(self, fieldInfo);
- }
- else
- {
- _il.Emit(OpCodes.Ldsfld, GetFieldInfo(fieldInfo));
- }
- }
- else
- {
- LoadMemberTarget(self, fieldInfo);
- _il.Emit(OpCodes.Ldfld, GetFieldInfo(fieldInfo));
- }
- PushType(fieldInfo.Type);
- }
-
- object GetStaticValue(IField field)
- {
- InternalField internalField = field as InternalField;
- if (null != internalField)
- {
- return GetInternalFieldStaticValue(internalField);
- }
- return field.StaticValue;
- }
-
- object GetInternalFieldStaticValue(InternalField field)
- {
- return GetValue(field.Type, (Expression)field.StaticValue);
- }
-
- void EmitLoadLiteralField(Node node, IField fieldInfo)
- {
- object value = GetStaticValue(fieldInfo);
- if (null == value)
- {
- _il.Emit(OpCodes.Ldnull);
- }
- else
- {
- TypeCode type = Type.GetTypeCode(value.GetType());
- switch (type)
- {
- case TypeCode.Byte:
- {
- _il.Emit(OpCodes.Ldc_I4, (int)(byte)value);
- _il.Emit(OpCodes.Conv_U1);
- break;
- }
-
- case TypeCode.SByte:
- {
- _il.Emit(OpCodes.Ldc_I4, (int)(sbyte)value);
- _il.Emit(OpCodes.Conv_I1);
- break;
- }
-
- case TypeCode.Char:
- {
- _il.Emit(OpCodes.Ldc_I4, (int)(char)value);
- break;
- }
-
- case TypeCode.Int16:
- {
- _il.Emit(OpCodes.Ldc_I4, (int)(short)value);
- break;
- }
-
- case TypeCode.UInt16:
- {
- _il.Emit(OpCodes.Ldc_I4, (int)(ushort)value);
- break;
- }
-
- case TypeCode.Int32:
- {
- _il.Emit(OpCodes.Ldc_I4, (int)value);
- break;
- }
-
- case TypeCode.UInt32:
- {
- uint uValue = (uint)value;
- unchecked
- {
- _il.Emit(OpCodes.Ldc_I4, (int)uValue);
- }
- _il.Emit(OpCodes.Conv_U4);
- break;
- }
-
- case TypeCode.Int64:
- {
- _il.Emit(OpCodes.Ldc_I8, (long)value);
- break;
- }
-
- case TypeCode.UInt64:
- {
- ulong uValue = (ulong)value;
- unchecked
- {
- _il.Emit(OpCodes.Ldc_I8, (long)uValue);
- }
- _il.Emit(OpCodes.Conv_U8);
- break;
- }
-
- case TypeCode.Single:
- {
- _il.Emit(OpCodes.Ldc_R4, (float)value);
- break;
- }
-
- case TypeCode.Double:
- {
- _il.Emit(OpCodes.Ldc_R8, (double)value);
- break;
- }
-
- case TypeCode.String:
- {
- _il.Emit(OpCodes.Ldstr, (string)value);
- break;
- }
-
- default:
- {
- NotImplemented(node, "Literal: " + type.ToString());
- break;
- }
- }
- }
- }
-
- override public void OnGenericReferenceExpression(GenericReferenceExpression node)
+#region license
+// Copyright (c) 2004, Rodrigo B. de Oliveira (rbo@acm.org)
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+// * Neither the name of Rodrigo B. de Oliveira nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#endregion
+
+using System;
+using System.Collections;
+using System.Diagnostics;
+using System.Diagnostics.SymbolStore;
+using System.IO;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Resources;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading;
+using Boo.Lang.Compiler.Ast;
+using Boo.Lang.Compiler.TypeSystem;
+using Boo.Lang.Runtime;
+using Attribute = Boo.Lang.Compiler.Ast.Attribute;
+using Module = Boo.Lang.Compiler.Ast.Module;
+
+namespace Boo.Lang.Compiler.Steps
+{
+ class LoopInfo
+ {
+ public Label BreakLabel;
+
+ public Label ContinueLabel;
+
+ public int TryBlockDepth;
+
+ public LoopInfo(Label breakLabel, Label continueLabel, int tryBlockDepth)
{
+ BreakLabel = breakLabel;
+ ContinueLabel = continueLabel;
+ TryBlockDepth = tryBlockDepth;
+ }
+ }
+
+ public class EmitAssembly : AbstractVisitorCompilerStep
+ {
+ static ConstructorInfo DebuggableAttribute_Constructor = typeof(DebuggableAttribute).GetConstructor(new Type[] { Types.Bool, Types.Bool });
+
+ static ConstructorInfo DuckTypedAttribute_Constructor = Types.DuckTypedAttribute.GetConstructor(new Type[0]);
+
+ static ConstructorInfo ParamArrayAttribute_Constructor = Types.ParamArrayAttribute.GetConstructor(new Type[0]);
+
+ static MethodInfo RuntimeServices_NormalizeArrayIndex = Types.RuntimeServices.GetMethod("NormalizeArrayIndex");
+
+ static MethodInfo RuntimeServices_ToBool_Object = Types.RuntimeServices.GetMethod("ToBool", new Type[] { Types.Object });
+
+ static MethodInfo RuntimeServices_ToBool_Decimal = Types.RuntimeServices.GetMethod("ToBool", new Type[] { Types.Decimal });
+
+ static MethodInfo Builtins_ArrayTypedConstructor = Types.Builtins.GetMethod("array", new Type[] { Types.Type, Types.Int });
+
+ static MethodInfo Builtins_ArrayTypedCollectionConstructor = Types.Builtins.GetMethod("array", new Type[] { Types.Type, Types.ICollection });
+
+ static MethodInfo Math_Pow = typeof(Math).GetMethod("Pow");
+
+ static ConstructorInfo List_EmptyConstructor = Types.List.GetConstructor(Type.EmptyTypes);
+
+ static ConstructorInfo List_ArrayBoolConstructor = Types.List.GetConstructor(new Type[] { Types.ObjectArray, Types.Bool });
+
+ static ConstructorInfo Hash_Constructor = Types.Hash.GetConstructor(new Type[0]);
+
+ static ConstructorInfo Regex_Constructor = typeof(Regex).GetConstructor(new Type[] { Types.String });
+
+ static MethodInfo Hash_Add = Types.Hash.GetMethod("Add", new Type[] { typeof(object), typeof(object) });
+
+ static ConstructorInfo TimeSpan_LongConstructor = Types.TimeSpan.GetConstructor(new Type[] { typeof(long) });
+
+ static MethodInfo Type_GetTypeFromHandle = Types.Type.GetMethod("GetTypeFromHandle");
+
+ AssemblyBuilder _asmBuilder;
+
+ ModuleBuilder _moduleBuilder;
+
+ Hashtable _symbolDocWriters = new Hashtable();
+
+ // IL generation state
+ ILGenerator _il;
+ Label _returnLabel; // current label for method return
+ LocalBuilder _returnValueLocal; // returnValueLocal
+ IType _returnType;
+ int _tryBlock; // are we in a try block?
+ bool _checked = true;
+ bool _rawArrayIndexing = false;
+ Hashtable _typeCache = new Hashtable();
+
+ // keeps track of types on the IL stack
+ Stack _types = new Stack();
+
+ Stack _loopInfoStack = new Stack();
+
+ AttributeCollection _assemblyAttributes = new AttributeCollection();
+
+ LoopInfo _currentLoopInfo;
+
+ void EnterLoop(Label breakLabel, Label continueLabel)
+ {
+ _loopInfoStack.Push(_currentLoopInfo);
+ _currentLoopInfo = new LoopInfo(breakLabel, continueLabel, _tryBlock);
+ }
+
+ bool InTryInLoop()
+ {
+ return _tryBlock > _currentLoopInfo.TryBlockDepth;
+ }
+
+ void LeaveLoop()
+ {
+ _currentLoopInfo = (LoopInfo)_loopInfoStack.Pop();
+ }
+
+ void PushType(IType type)
+ {
+ _types.Push(type);
+ }
+
+ void PushBool()
+ {
+ PushType(TypeSystemServices.BoolType);
+ }
+
+ void PushVoid()
+ {
+ PushType(TypeSystemServices.VoidType);
+ }
+
+ IType PopType()
+ {
+ return (IType)_types.Pop();
+ }
+
+ IType PeekTypeOnStack()
+ {
+ return (IType)_types.Peek();
+ }
+
+ void AssertStackIsEmpty(string message)
+ {
+ if (0 != _types.Count)
+ {
+ throw new ApplicationException(
+ string.Format("{0}: {1} items still on the stack.", message, _types.Count)
+ );
+ }
+ }
+
+ override public void Run()
+ {
+ if (Errors.Count > 0)
+ {
+ return;
+ }
+
+ GatherAssemblyAttributes();
+ SetUpAssembly();
+
+ DefineTypes();
+
+ DefineResources();
+ DefineAssemblyAttributes();
+ DefineEntryPoint();
+ }
+
+ void GatherAssemblyAttributes()
+ {
+ foreach (Module module in CompileUnit.Modules)
+ {
+ foreach (Attribute attribute in module.AssemblyAttributes)
+ {
+ _assemblyAttributes.Add(attribute);
+ }
+ }
+ }
+
+ void DefineTypes()
+ {
+ if (CompileUnit.Modules.Count > 0)
+ {
+ List types = CollectTypes();
+
+ foreach (TypeDefinition type in types)
+ {
+ DefineType(type);
+ }
+
+ foreach (TypeDefinition type in types)
+ {
+ DefineTypeMembers(type);
+ }
+
+ foreach (Module module in CompileUnit.Modules)
+ {
+ OnModule(module);
+ }
+
+ EmitAttributes();
+ CreateTypes(types);
+ }
+ }
+
+ class AttributeEmitVisitor : DepthFirstVisitor
+ {
+ EmitAssembly _emitter;
+
+ public AttributeEmitVisitor(EmitAssembly emitter)
+ {
+ _emitter = emitter;
+ }
+
+ public override void OnField(Field node)
+ {
+ _emitter.EmitFieldAttributes(node);
+ }
+
+ public override void OnEnumMember(EnumMember node)
+ {
+ _emitter.EmitFieldAttributes(node);
+ }
+
+ public override void OnEvent(Event node)
+ {
+ _emitter.EmitEventAttributes(node);
+ }
+
+ public override void OnProperty(Property node)
+ {
+ Visit(node.Getter);
+ Visit(node.Setter);
+ _emitter.EmitPropertyAttributes(node);
+ }
+
+ public override void OnConstructor(Constructor node)
+ {
+ Visit(node.Parameters);
+ _emitter.EmitConstructorAttributes(node);
+ }
+
+ public override void OnMethod(Method node)
+ {
+ Visit(node.Parameters);
+ _emitter.EmitMethodAttributes(node);
+ }
+
+ public override void OnParameterDeclaration(ParameterDeclaration node)
+ {
+ _emitter.EmitParameterAttributes(node);
+ }
+
+ public override void LeaveClassDefinition(ClassDefinition node)
+ {
+ _emitter.EmitTypeAttributes(node);
+ }
+
+ public override void LeaveInterfaceDefinition(InterfaceDefinition node)
+ {
+ _emitter.EmitTypeAttributes(node);
+ }
+
+ public override void LeaveEnumDefinition(EnumDefinition node)
+ {
+ _emitter.EmitTypeAttributes(node);
+ }
+ }
+
+ delegate void CustomAttributeSetter(CustomAttributeBuilder attribute);
+
+ void EmitAttributes(INodeWithAttributes node, CustomAttributeSetter setCustomAttribute)
+ {
+ foreach (Attribute attribute in node.Attributes)
+ {
+ setCustomAttribute(GetCustomAttributeBuilder(attribute));
+ }
+ }
+
+ void EmitPropertyAttributes(Property node)
+ {
+ PropertyBuilder builder = GetPropertyBuilder(node);
+ EmitAttributes(node, new CustomAttributeSetter(builder.SetCustomAttribute));
+ }
+
+ void EmitParameterAttributes(ParameterDeclaration node)
+ {
+ ParameterBuilder builder = (ParameterBuilder)GetBuilder(node);
+ EmitAttributes(node, new CustomAttributeSetter(builder.SetCustomAttribute));
+ }
+
+ void EmitEventAttributes(Event node)
+ {
+ EventBuilder builder = (EventBuilder)GetBuilder(node);
+ EmitAttributes(node, new CustomAttributeSetter(builder.SetCustomAttribute));
+ }
+
+ void EmitConstructorAttributes(Constructor node)
+ {
+ ConstructorBuilder builder = (ConstructorBuilder)GetBuilder(node);
+ EmitAttributes(node, new CustomAttributeSetter(builder.SetCustomAttribute));
+ }
+
+ void EmitMethodAttributes(Method node)
+ {
+ MethodBuilder builder = GetMethodBuilder(node);
+ EmitAttributes(node, new CustomAttributeSetter(builder.SetCustomAttribute));
+ }
+
+ void EmitTypeAttributes(TypeDefinition node)
+ {
+ TypeBuilder builder = GetTypeBuilder(node);
+ EmitAttributes(node, new CustomAttributeSetter(builder.SetCustomAttribute));
+ }
+
+ void EmitFieldAttributes(TypeMember node)
+ {
+ FieldBuilder builder = GetFieldBuilder(node);
+ EmitAttributes(node, new CustomAttributeSetter(builder.SetCustomAttribute));
+ }
+
+ void EmitAttributes()
+ {
+ AttributeEmitVisitor visitor = new AttributeEmitVisitor(this);
+ foreach (Module module in CompileUnit.Modules)
+ {
+ module.Accept(visitor);
+ }
+ }
+
+ void CreateTypes(List types)
+ {
+ new TypeCreator(this, types).Run();
+ }
+
+ ///
+ /// Ensures that all types are created in the correct order.
+ ///
+ class TypeCreator
+ {
+ EmitAssembly _emitter;
+
+ Hashtable _created;
+
+ List _types;
+
+ TypeMember _current;
+
+ public TypeCreator(EmitAssembly emitter, List types)
+ {
+ _emitter = emitter;
+ _types = types;
+ _created = new Hashtable();
+ }
+
+ public void Run()
+ {
+ ResolveEventHandler resolveHandler = new ResolveEventHandler(OnTypeResolve);
+ AppDomain current = Thread.GetDomain();
+
+ try
+ {
+ current.TypeResolve += resolveHandler;
+ CreateTypes();
+ }
+ finally
+ {
+ current.TypeResolve -= resolveHandler;
+ }
+ }
+
+ void CreateTypes()
+ {
+ foreach (TypeMember type in _types)
+ {
+ CreateType(type);
+ }
+ }
+
+ void CreateType(TypeMember type)
+ {
+ if (!_created.ContainsKey(type))
+ {
+ TypeMember saved = _current;
+ _current = type;
+
+ _created.Add(type, type);
+
+ Trace("creating type '{0}'", type);
+
+ if (IsNestedType(type))
+ {
+ CreateType((TypeMember)type.ParentNode);
+ }
+
+ TypeDefinition typedef = type as TypeDefinition;
+ if (null != typedef)
+ {
+ foreach (TypeReference baseTypeRef in typedef.BaseTypes)
+ {
+ AbstractInternalType tag = _emitter.GetType(baseTypeRef) as AbstractInternalType;
+ if (null != tag)
+ {
+ CreateType(tag.TypeDefinition);
+ }
+ }
+ }
+
+ ((AbstractInternalType)type.Entity).GeneratedType = _emitter.GetTypeBuilder(type).CreateType();
+
+ Trace("type '{0}' successfully created", type);
+
+ _current = saved;
+ }
+ }
+
+ bool IsNestedType(TypeMember type)
+ {
+ NodeType parent = type.ParentNode.NodeType;
+ return (NodeType.ClassDefinition == parent) ||
+ (NodeType.InterfaceDefinition == parent);
+ }
+
+ Assembly OnTypeResolve(object sender, ResolveEventArgs args)
+ {
+ Trace("OnTypeResolve('{0}') during '{1}' creation.", args.Name, _current);
+
+ // TypeResolve is generated whenever a type
+ // contains fields of a value type not created yet.
+ // All we need to do is look for value type fields
+ // and create them all.
+ ClassDefinition classdef = _current as ClassDefinition;
+ foreach (TypeMember member in classdef.Members)
+ {
+ if (NodeType.Field == member.NodeType)
+ {
+ AbstractInternalType type = _emitter.GetType(((Field)member).Type) as AbstractInternalType;
+ if (type != null && type.IsValueType)
+ {
+ CreateType(type.TypeDefinition);
+ }
+ }
+ }
+
+ return _emitter._asmBuilder;
+ }
+
+ void Trace(string format, params object[] args)
+ {
+ _emitter.Context.TraceVerbose(format, args);
+ }
+ }
+
+ List CollectTypes()
+ {
+ List types = new List();
+ foreach (Module module in CompileUnit.Modules)
+ {
+ CollectTypes(types, module.Members);
+ }
+ return types;
+ }
+
+ void CollectTypes(List types, TypeMemberCollection members)
+ {
+ foreach (TypeMember member in members)
+ {
+ switch (member.NodeType)
+ {
+ case NodeType.InterfaceDefinition:
+ case NodeType.ClassDefinition:
+ {
+ types.Add(member);
+ CollectTypes(types, ((TypeDefinition)member).Members);
+ break;
+ }
+ case NodeType.EnumDefinition:
+ {
+ types.Add(member);
+ break;
+ }
+ }
+ }
+ }
+
+ override public void Dispose()
+ {
+ base.Dispose();
+
+ _asmBuilder = null;
+ _moduleBuilder = null;
+ _symbolDocWriters.Clear();
+ _il = null;
+ _returnValueLocal = null;
+ _returnType = null;
+ _tryBlock = 0;
+ _checked = true;
+ _rawArrayIndexing = false;
+ _types.Clear();
+ _typeCache.Clear();
+ _builders.Clear();
+ _assemblyAttributes.Clear();
+ }
+
+ override public void OnAttribute(Attribute node)
+ {
+ }
+
+ override public void OnModule(Module module)
+ {
+ Visit(module.Members);
+ }
+
+ override public void OnEnumDefinition(EnumDefinition node)
+ {
+ Type baseType = typeof(int);
+
+ TypeBuilder builder = GetTypeBuilder(node);
+
+ builder.DefineField("value__", baseType,
+ FieldAttributes.Public |
+ FieldAttributes.SpecialName |
+ FieldAttributes.RTSpecialName);
+
+ foreach (EnumMember member in node.Members)
+ {
+ FieldBuilder field = builder.DefineField(member.Name, builder,
+ FieldAttributes.Public |
+ FieldAttributes.Static |
+ FieldAttributes.Literal);
+ field.SetConstant((int)member.Initializer.Value);
+ SetBuilder(member, field);
+ }
+ }
+
+ override public void OnArrayTypeReference(ArrayTypeReference node)
+ {
+ }
+
+ override public void OnClassDefinition(ClassDefinition node)
+ {
+ EmitTypeDefinition(node);
+ }
+
+ override public void OnField(Field node)
+ {
+ FieldBuilder builder = GetFieldBuilder(node);
+ if (builder.IsLiteral)
+ {
+ builder.SetConstant(GetInternalFieldStaticValue((InternalField)node.Entity));
+ }
+ }
+
+ override public void OnInterfaceDefinition(InterfaceDefinition node)
+ {
+ TypeBuilder builder = GetTypeBuilder(node);
+ foreach (TypeReference baseType in node.BaseTypes)
+ {
+ builder.AddInterfaceImplementation(GetSystemType(baseType));
+ }
+ }
+
+ override public void OnCallableDefinition(CallableDefinition node)
+ {
+ NotImplemented(node, "Unexpected callable definition!");
+ }
+
+ void EmitTypeDefinition(TypeDefinition node)
+ {
+ TypeBuilder current = GetTypeBuilder(node);
+ EmitBaseTypesAndAttributes(node, current);
+ Visit(node.Members);
+ }
+
+ override public void OnMethod(Method method)
+ {
+ if (method.IsRuntime) return;
+ if (IsPInvoke(method)) return;
+
+ MethodBuilder methodBuilder = GetMethodBuilder(method);
+ if (null != method.ExplicitInfo)
+ {
+ IMethod ifaceMethod = (IMethod)method.ExplicitInfo.Entity;
+ MethodInfo ifaceInfo = GetMethodInfo(ifaceMethod);
+ MethodInfo implInfo = GetMethodInfo((IMethod)method.Entity);
+
+ TypeBuilder typeBuilder = GetTypeBuilder(method.DeclaringType);
+ typeBuilder.DefineMethodOverride(implInfo, ifaceInfo);
+ }
+
+ EmitMethod(method, methodBuilder.GetILGenerator());
+ }
+
+ void EmitMethod(Method method, ILGenerator generator)
+ {
+ _il = generator;
+
+ DefineLabels(method);
+ Visit(method.Locals);
+
+ BeginMethodBody(GetEntity(method).ReturnType);
+ Visit(method.Body);
+ EndMethodBody();
+ }
+
+ void BeginMethodBody(IType returnType)
+ {
+ _returnType = returnType;
+ _returnLabel = _il.DefineLabel();
+ if (TypeSystemServices.VoidType != _returnType)
+ {
+ _returnValueLocal = _il.DeclareLocal(GetSystemType(_returnType));
+ }
+ }
+
+ void EndMethodBody()
+ {
+ _il.MarkLabel(_returnLabel);
+ if (null != _returnValueLocal)
+ {
+ _il.Emit(OpCodes.Ldloc, _returnValueLocal);
+ _returnValueLocal = null;
+ }
+ _il.Emit(OpCodes.Ret);
+ }
+
+ private bool IsPInvoke(Method method)
+ {
+ return GetEntity(method).IsPInvoke;
+ }
+
+ override public void OnBlock(Block block)
+ {
+ bool currentChecked = _checked;
+ _checked = AstAnnotations.IsChecked(block);
+
+ bool currentArrayIndexing = _rawArrayIndexing;
+ _rawArrayIndexing = AstAnnotations.IsRawIndexing(block);
+
+ Visit(block.Statements);
+
+ _rawArrayIndexing = currentArrayIndexing;
+ _checked = currentChecked;
+ }
+
+ void DefineLabels(Method method)
+ {
+ foreach (InternalLabel label in ((InternalMethod)method.Entity).Labels)
+ {
+ label.Label = _il.DefineLabel();
+ }
+ }
+
+ override public void OnConstructor(Constructor constructor)
+ {
+ if (constructor.IsRuntime) return;
+
+ ConstructorBuilder builder = GetConstructorBuilder(constructor);
+ EmitMethod(constructor, builder.GetILGenerator());
+ }
+
+ override public void OnLocal(Local local)
+ {
+ InternalLocal info = GetInternalLocal(local);
+ info.LocalBuilder = _il.DeclareLocal(GetSystemType(local));
+ if (Parameters.Debug)
+ {
+ info.LocalBuilder.SetLocalSymInfo(local.Name);
+ }
+ }
+
+ override public void OnForStatement(ForStatement node)
+ {
+ NotImplemented("ForStatement");
+ }
+
+ override public void OnReturnStatement(ReturnStatement node)
+ {
+ EmitDebugInfo(node);
+ OpCode retOpCode = _tryBlock > 0 ? OpCodes.Leave : OpCodes.Br;
+
+ if (null != node.Expression)
+ {
+ Visit(node.Expression);
+ EmitCastIfNeeded(_returnType, PopType());
+ _il.Emit(OpCodes.Stloc, _returnValueLocal);
+ }
+ _il.Emit(retOpCode, _returnLabel);
+ EmitNopDebugInfo(node);
+ }
+
+ override public void OnRaiseStatement(RaiseStatement node)
+ {
+ EmitDebugInfo(node);
+ if (node.Exception == null)
+ {
+ _il.Emit(OpCodes.Rethrow);
+ }
+ else
+ {
+ Visit(node.Exception); PopType();
+ _il.Emit(OpCodes.Throw);
+ }
+ EmitNopDebugInfo(node);
+ }
+
+ private void EmitNopDebugInfo(Statement node)
+ {
+ // HACK: workaround - mono reports the position of
+ // raise as being the position of the next instruction
+ // after it
+ if (EmitDebugInfo(node))
+ {
+ _il.Emit(OpCodes.Nop);
+ }
+ }
+
+ override public void OnTryStatement(TryStatement node)
+ {
+ ++_tryBlock;
+
+ _il.BeginExceptionBlock();
+ Visit(node.ProtectedBlock);
+ Visit(node.ExceptionHandlers);
+ if (null != node.EnsureBlock)
+ {
+ _il.BeginFinallyBlock();
+ Visit(node.EnsureBlock);
+ }
+ _il.EndExceptionBlock();
+
+ --_tryBlock;
+ }
+
+ override public void OnExceptionHandler(ExceptionHandler node)
+ {
+ _il.BeginCatchBlock(GetSystemType(node.Declaration));
+ _il.Emit(OpCodes.Stloc, GetLocalBuilder(node.Declaration));
+ Visit(node.Block);
+ }
+
+ override public void OnUnpackStatement(UnpackStatement node)
+ {
+ NotImplemented("Unpacking");
+ }
+
+ override public bool EnterExpressionStatement(ExpressionStatement node)
+ {
+ EmitDebugInfo(node);
+ return true;
+ }
+
+ override public void LeaveExpressionStatement(ExpressionStatement node)
+ {
+ // if the type of the inner expression is not
+ // void we need to pop its return value to leave
+ // the stack sane
+ DiscardValueOnStack();
+ AssertStackIsEmpty("stack must be empty after a statement!");
+
+ EmitNopDebugInfo(node);
+ }
+
+ void DiscardValueOnStack()
+ {
+ if (PopType() != TypeSystemServices.VoidType)
+ {
+ _il.Emit(OpCodes.Pop);
+ }
+ }
+
+ override public void OnUnlessStatement(UnlessStatement node)
+ {
+ Label endLabel = _il.DefineLabel();
+ EmitDebugInfo(node);
+ EmitBranchTrue(node.Condition, endLabel);
+ EmitNopDebugInfo(node);
+ node.Block.Accept(this);
+ _il.MarkLabel(endLabel);
+ }
+
+ void OnSwitch(MethodInvocationExpression node)
+ {
+ ExpressionCollection args = node.Arguments;
+ Visit(args[0]);
+ EmitCastIfNeeded(TypeSystemServices.IntType, PopType());
+
+ Label[] labels = new Label[args.Count-1];
+ for (int i=0; i 0)
+ {
+ EmitObjectArray(node.Items);
+ _il.Emit(OpCodes.Ldc_I4_1);
+ _il.Emit(OpCodes.Newobj, List_ArrayBoolConstructor);
+ }
+ else
+ {
+ _il.Emit(OpCodes.Newobj, List_EmptyConstructor);
+ }
+ PushType(TypeSystemServices.ListType);
+ }
+
+ override public void OnArrayLiteralExpression(ArrayLiteralExpression node)
+ {
+ IArrayType type = (IArrayType)node.ExpressionType;
+ EmitArray(type.GetElementType(), node.Items);
+ PushType(type);
+ }
+
+ override public void OnRELiteralExpression(RELiteralExpression node)
+ {
+ _il.Emit(OpCodes.Ldstr, RuntimeServices.Mid(node.Value, 1, -1));
+ _il.Emit(OpCodes.Newobj, Regex_Constructor);
+ PushType(node.ExpressionType);
+ }
+
+ override public void OnStringLiteralExpression(StringLiteralExpression node)
+ {
+ _il.Emit(OpCodes.Ldstr, node.Value);
+ PushType(TypeSystemServices.StringType);
+ }
+
+ override public void OnCharLiteralExpression(CharLiteralExpression node)
+ {
+ _il.Emit(OpCodes.Ldc_I4, node.Value[0]);
+ PushType(TypeSystemServices.CharType);
+ }
+
+ override public void OnSlicingExpression(SlicingExpression node)
+ {
+ if (AstUtil.IsLhsOfAssignment(node))
+ {
+ return;
+ }
+
+ Visit(node.Target);
+
+ IArrayType type = (IArrayType)PopType();
+ EmitNormalizedArrayIndex(node, node.Indices[0].Begin);
+
+ IType elementType = type.GetElementType();
+ OpCode opcode = GetLoadEntityOpCode(elementType);
+ if (OpCodes.Ldelema.Value == opcode.Value)
+ {
+ Type systemType = GetSystemType(elementType);
+ _il.Emit(opcode, systemType);
+ _il.Emit(OpCodes.Ldobj, systemType);
+ }
+ else
+ {
+ _il.Emit(opcode);
+ }
+ PushType(elementType);
+ }
+
+ void EmitNormalizedArrayIndex(SlicingExpression sourceNode, Expression index)
+ {
+ bool isNegative = false;
+ if (CanBeNegative(index, ref isNegative)
+ && !_rawArrayIndexing
+ && !AstAnnotations.IsRawIndexing(sourceNode))
+ {
+ if (isNegative)
+ {
+ _il.Emit(OpCodes.Dup);
+ _il.Emit(OpCodes.Ldlen);
+ EmitLoadInt(index);
+ _il.Emit(OpCodes.Add);
+ }
+ else
+ {
+ _il.Emit(OpCodes.Dup);
+ EmitLoadInt(index);
+ _il.EmitCall(OpCodes.Call, RuntimeServices_NormalizeArrayIndex, null);
+ }
+ }
+ else
+ {
+ EmitLoadInt(index);
+ }
+ }
+
+ bool CanBeNegative(Expression expression, ref bool isNegative)
+ {
+ IntegerLiteralExpression integer = expression as IntegerLiteralExpression;
+ if (null != integer)
+ {
+ if (integer.Value >= 0)
+ {
+ return false;
+ }
+ isNegative = true;
+ }
+ return true;
+ }
+
+ void EmitLoadInt(Expression expression)
+ {
+ Visit(expression);
+ EmitCastIfNeeded(TypeSystemServices.IntType, PopType());
+ }
+
+ override public void OnExpressionInterpolationExpression(ExpressionInterpolationExpression node)
+ {
+ Type stringBuilderType = typeof(StringBuilder);
+ ConstructorInfo constructor = stringBuilderType.GetConstructor(new Type[0]);
+ MethodInfo appendObject = stringBuilderType.GetMethod("Append", new Type[] { typeof(object) });
+ MethodInfo appendString = stringBuilderType.GetMethod("Append", new Type[] { typeof(string) });
+
+ _il.Emit(OpCodes.Newobj, constructor);
+
+ foreach (Expression arg in node.Expressions)
+ {
+ Visit(arg);
+
+ IType argType = PopType();
+ if (TypeSystemServices.StringType == argType)
+ {
+ _il.EmitCall(OpCodes.Call, appendString, null);
+ }
+ else
+ {
+ EmitCastIfNeeded(TypeSystemServices.ObjectType, argType);
+ _il.EmitCall(OpCodes.Call, appendObject, null);
+ }
+ }
+ _il.EmitCall(OpCodes.Call, stringBuilderType.GetMethod("ToString", new Type[0]), null);
+ PushType(TypeSystemServices.StringType);
+ }
+
+ void LoadMemberTarget(Expression self, IMember member)
+ {
+ if (member.DeclaringType.IsValueType)
+ {
+ LoadAddress(self);
+ }
+ else
+ {
+ Visit(self);
+ PopType();
+ }
+ }
+
+ void EmitLoadFieldAddress(Expression expression, IField field)
+ {
+ if (field.IsStatic)
+ {
+ _il.Emit(OpCodes.Ldsflda, GetFieldInfo(field));
+ }
+ else
+ {
+ LoadMemberTarget(((MemberReferenceExpression)expression).Target, field);
+ _il.Emit(OpCodes.Ldflda, GetFieldInfo(field));
+ }
+ }
+
+ void EmitLoadField(Expression self, IField fieldInfo)
+ {
+ if (fieldInfo.IsStatic)
+ {
+ if (fieldInfo.IsLiteral)
+ {
+ EmitLoadLiteralField(self, fieldInfo);
+ }
+ else
+ {
+ _il.Emit(OpCodes.Ldsfld, GetFieldInfo(fieldInfo));
+ }
+ }
+ else
+ {
+ LoadMemberTarget(self, fieldInfo);
+ _il.Emit(OpCodes.Ldfld, GetFieldInfo(fieldInfo));
+ }
+ PushType(fieldInfo.Type);
+ }
+
+ object GetStaticValue(IField field)
+ {
+ InternalField internalField = field as InternalField;
+ if (null != internalField)
+ {
+ return GetInternalFieldStaticValue(internalField);
+ }
+ return field.StaticValue;
+ }
+
+ object GetInternalFieldStaticValue(InternalField field)
+ {
+ return GetValue(field.Type, (Expression)field.StaticValue);
+ }
+
+ void EmitLoadLiteralField(Node node, IField fieldInfo)
+ {
+ object value = GetStaticValue(fieldInfo);
+ if (null == value)
+ {
+ _il.Emit(OpCodes.Ldnull);
+ }
+ else
+ {
+ TypeCode type = Type.GetTypeCode(value.GetType());
+ switch (type)
+ {
+ case TypeCode.Byte:
+ {
+ _il.Emit(OpCodes.Ldc_I4, (int)(byte)value);
+ _il.Emit(OpCodes.Conv_U1);
+ break;
+ }
+
+ case TypeCode.SByte:
+ {
+ _il.Emit(OpCodes.Ldc_I4, (int)(sbyte)value);
+ _il.Emit(OpCodes.Conv_I1);
+ break;
+ }
+
+ case TypeCode.Char:
+ {
+ _il.Emit(OpCodes.Ldc_I4, (int)(char)value);
+ break;
+ }
+
+ case TypeCode.Int16:
+ {
+ _il.Emit(OpCodes.Ldc_I4, (int)(short)value);
+ break;
+ }
+
+ case TypeCode.UInt16:
+ {
+ _il.Emit(OpCodes.Ldc_I4, (int)(ushort)value);
+ break;
+ }
+
+ case TypeCode.Int32:
+ {
+ _il.Emit(OpCodes.Ldc_I4, (int)value);
+ break;
+ }
+
+ case TypeCode.UInt32:
+ {
+ uint uValue = (uint)value;
+ unchecked
+ {
+ _il.Emit(OpCodes.Ldc_I4, (int)uValue);
+ }
+ _il.Emit(OpCodes.Conv_U4);
+ break;
+ }
+
+ case TypeCode.Int64:
+ {
+ _il.Emit(OpCodes.Ldc_I8, (long)value);
+ break;
+ }
+
+ case TypeCode.UInt64:
+ {
+ ulong uValue = (ulong)value;
+ unchecked
+ {
+ _il.Emit(OpCodes.Ldc_I8, (long)uValue);
+ }
+ _il.Emit(OpCodes.Conv_U8);
+ break;
+ }
+
+ case TypeCode.Single:
+ {
+ _il.Emit(OpCodes.Ldc_R4, (float)value);
+ break;
+ }
+
+ case TypeCode.Double:
+ {
+ _il.Emit(OpCodes.Ldc_R8, (double)value);
+ break;
+ }
+
+ case TypeCode.String:
+ {
+ _il.Emit(OpCodes.Ldstr, (string)value);
+ break;
+ }
+
+ default:
+ {
+ NotImplemented(node, "Literal: " + type.ToString());
+ break;
+ }
+ }
+ }
+ }
+
+ override public void OnGenericReferenceExpression(GenericReferenceExpression node)
+ {
IEntity tag = TypeSystem.TypeSystemServices.GetEntity(node);
switch (tag.EntityType)
{
@@ -2592,2073 +2592,2106 @@
break;
}
}
- }
-
- override public void OnMemberReferenceExpression(MemberReferenceExpression node)
- {
- IEntity tag = TypeSystem.TypeSystemServices.GetEntity(node);
- switch (tag.EntityType)
- {
- case EntityType.Method:
- {
- node.Target.Accept(this);
- break;
- }
-
- case EntityType.Field:
- {
- EmitLoadField(node.Target, (IField)tag);
- break;
- }
-
- case EntityType.Type:
- {
- EmitGetTypeFromHandle(GetSystemType(node));
- break;
- }
-
- default:
- {
- NotImplemented(node, tag.ToString());
- break;
- }
- }
- }
-
- void LoadAddress(Expression expression)
- {
- if (NodeType.SelfLiteralExpression == expression.NodeType)
- {
- if (expression.ExpressionType.IsValueType)
- {
- _il.Emit(OpCodes.Ldarg_0);
- return;
- }
- }
-
- IEntity tag = expression.Entity;
- if (null != tag)
- {
- switch (tag.EntityType)
- {
- case EntityType.Local:
- {
- _il.Emit(OpCodes.Ldloca, ((InternalLocal)tag).LocalBuilder);
- return;
- }
-
- case EntityType.Parameter:
- {
- InternalParameter param = (InternalParameter)tag;
- if (param.Parameter.IsByRef)
- {
- LoadParam(param);
- }
- else
- {
- _il.Emit(OpCodes.Ldarga, param.Index);
- }
- return;
- }
-
- case EntityType.Field:
- {
- IField field = (IField)tag;
- if (!field.IsLiteral)
- {
- EmitLoadFieldAddress(expression, field);
- return;
- }
- break;
- }
- }
- }
-
- if (IsValueTypeArraySlicing(expression))
- {
- SlicingExpression slicing = (SlicingExpression)expression;
- Visit(slicing.Target);
- IArrayType arrayType = (IArrayType)PopType();
- EmitNormalizedArrayIndex(slicing, slicing.Indices[0].Begin);
- _il.Emit(OpCodes.Ldelema, GetSystemType(arrayType.GetElementType()));
- }
- else
- {
- // declare local to hold value type
- Visit(expression);
- LocalBuilder temp = _il.DeclareLocal(GetSystemType(PopType()));
- _il.Emit(OpCodes.Stloc, temp);
- _il.Emit(OpCodes.Ldloca, temp);
- }
- }
-
- bool IsValueTypeArraySlicing(Expression expression)
- {
- SlicingExpression slicing = expression as SlicingExpression;
- if (null != slicing)
- {
- IArrayType type = (IArrayType)slicing.Target.ExpressionType;
- return type.GetElementType().IsValueType;
- }
- return false;
- }
-
- override public void OnSelfLiteralExpression(SelfLiteralExpression node)
- {
- _il.Emit(OpCodes.Ldarg_0);
- if (node.ExpressionType.IsValueType)
- {
- _il.Emit(OpCodes.Ldobj, GetSystemType(node.ExpressionType));
- }
- PushType(node.ExpressionType);
- }
-
- override public void OnSuperLiteralExpression(SuperLiteralExpression node)
- {
- _il.Emit(OpCodes.Ldarg_0);
- if (node.ExpressionType.IsValueType)
- {
- _il.Emit(OpCodes.Ldobj, GetSystemType(node.ExpressionType));
- }
- PushType(node.ExpressionType);
- }
-
- override public void OnNullLiteralExpression(NullLiteralExpression node)
- {
- _il.Emit(OpCodes.Ldnull);
- PushType(null);
- }
-
- override public void OnReferenceExpression(ReferenceExpression node)
- {
- IEntity info = TypeSystem.TypeSystemServices.GetEntity(node);
- switch (info.EntityType)
- {
- case EntityType.Local:
- {
- InternalLocal local = (InternalLocal)info;
- LocalBuilder builder = local.LocalBuilder;
- _il.Emit(OpCodes.Ldloc, builder);
- PushType(local.Type);
- break;
- }
-
- case EntityType.Parameter:
- {
- InternalParameter param = (InternalParameter)info;
- LoadParam(param);
-
- if (param.Parameter.IsByRef)
- {
- OpCode code = GetLoadRefParamCode(param.Type);
- if (code.Value == OpCodes.Ldobj.Value)
- {
- _il.Emit(code, GetSystemType(param.Type));
- }
- else {
- _il.Emit(code);
- }
- }
- PushType(param.Type);
- break;
- }
-
- case EntityType.Array:
- case EntityType.Type:
- {
- EmitGetTypeFromHandle(GetSystemType(node));
- break;
- }
-
- default:
- {
- NotImplemented(node, info.ToString());
- break;
- }
-
- }
- }
-
- void LoadParam(InternalParameter param)
- {
- int index = param.Index;
-
- switch (index)
- {
- case 0:
- {
- _il.Emit(OpCodes.Ldarg_0);
- break;
- }
-
- case 1:
- {
- _il.Emit(OpCodes.Ldarg_1);
- break;
- }
-
- case 2:
- {
- _il.Emit(OpCodes.Ldarg_2);
- break;
- }
-
- case 3:
- {
- _il.Emit(OpCodes.Ldarg_3);
- break;
- }
-
- default:
- {
- if (index < 256)
- {
- _il.Emit(OpCodes.Ldarg_S, index);
- }
- else
- {
- _il.Emit(OpCodes.Ldarg, index);
- }
- break;
- }
- }
- }
- void SetLocal(BinaryExpression node, InternalLocal tag, bool leaveValueOnStack)
- {
- node.Right.Accept(this); // leaves type on stack
-
- IType typeOnStack = null;
-
- if (leaveValueOnStack)
- {
- typeOnStack = PeekTypeOnStack();
- _il.Emit(OpCodes.Dup);
- }
- else
- {
- typeOnStack = PopType();
- }
- EmitAssignment(tag, typeOnStack);
- }
-
- void EmitAssignment(InternalLocal tag, IType typeOnStack)
- {
- // todo: assignment result must be type on the left in the
- // case of casting
- LocalBuilder local = tag.LocalBuilder;
- EmitCastIfNeeded(tag.Type, typeOnStack);
- _il.Emit(OpCodes.Stloc, local);
- }
-
- void SetField(Node sourceNode, IField field, Expression reference, Expression value, bool leaveValueOnStack)
- {
- OpCode opSetField = OpCodes.Stsfld;
- if (!field.IsStatic)
- {
- opSetField = OpCodes.Stfld;
- if (null != reference)
- {
- LoadMemberTarget(
- ((MemberReferenceExpression)reference).Target,
- field);
- }
- }
-
- value.Accept(this);
- EmitCastIfNeeded(field.Type, PopType());
-
- FieldInfo fi = GetFieldInfo(field);
- LocalBuilder local = null;
- if (leaveValueOnStack)
- {
- _il.Emit(OpCodes.Dup);
- local = _il.DeclareLocal(fi.FieldType);
- _il.Emit(OpCodes.Stloc, local);
- }
-
- _il.Emit(opSetField, fi);
-
- if (leaveValueOnStack)
- {
- _il.Emit(OpCodes.Ldloc, local);
- PushType(field.Type);
- }
- }
-
- void SetProperty(Node sourceNode, IProperty property, Expression reference, Expression value, bool leaveValueOnStack)
- {
- OpCode callOpCode = OpCodes.Call;
-
- MethodInfo setMethod = GetMethodInfo(property.GetSetMethod());
-
- if (null != reference)
- {
- if (!setMethod.IsStatic)
- {
- Expression target = ((MemberReferenceExpression)reference).Target;
- if (setMethod.DeclaringType.IsValueType)
- {
- LoadAddress(target);
- }
- else
- {
- callOpCode = OpCodes.Callvirt;
- target.Accept(this);
- PopType();
- }
- }
- }
-
- value.Accept(this);
- EmitCastIfNeeded(property.Type, PopType());
-
- LocalBuilder local = null;
- if (leaveValueOnStack)
- {
- _il.Emit(OpCodes.Dup);
- local = _il.DeclareLocal(GetSystemType(property.Type));
- _il.Emit(OpCodes.Stloc, local);
- }
-
- _il.EmitCall(callOpCode, setMethod, null);
-
- if (leaveValueOnStack)
- {
- _il.Emit(OpCodes.Ldloc, local);
- PushType(property.Type);
- }
- }
-
- bool EmitDebugInfo(Node node)
- {
- return EmitDebugInfo(node, node);
- }
-
- bool EmitDebugInfo(Node startNode, Node endNode)
- {
- if (!Parameters.Debug) return false;
-
- LexicalInfo start = startNode.LexicalInfo;
- if (!start.IsValid) return false;
-
- ISymbolDocumentWriter writer = GetDocumentWriter(start.FullPath);
- if (null == writer) return false;
-
- try
- {
- _il.MarkSequencePoint(writer, start.Line, 0, start.Line+1, 0);
- }
- catch (Exception x)
- {
- Error(CompilerErrorFactory.InternalError(startNode, x));
- return false;
- }
-
- return true;
- }
-
- private ISymbolDocumentWriter GetDocumentWriter(string fname)
- {
- ISymbolDocumentWriter writer = GetCachedDocumentWriter(fname);
- if (null != writer) return writer;
-
- writer = _moduleBuilder.DefineDocument(
- fname,
- Guid.Empty,
- Guid.Empty,
- SymDocumentType.Text);
- _symbolDocWriters.Add(fname, writer);
-
- return writer;
- }
-
- private ISymbolDocumentWriter GetCachedDocumentWriter(string fname)
- {
- return (ISymbolDocumentWriter) _symbolDocWriters[fname];
- }
-
- bool IsBoolOrInt(IType type)
- {
- return TypeSystemServices.BoolType == type ||
- TypeSystemServices.IntType == type;
- }
-
- void PushArguments(IMethodBase entity, ExpressionCollection args)
- {
- IParameter[] parameters = entity.GetParameters();
- for (int i=0; i 1)
- {
- type = Array.CreateInstance(GetSystemType(arrayType.GetElementType()), new int[arrayType.GetArrayRank()]).GetType();
- }
- else
- {
- type = Array.CreateInstance(GetSystemType(arrayType.GetElementType()), 0).GetType();
- }
- }
- }
- else
- {
- if (Null.Default == tag)
- {
- type = Types.Object;
- }
- else
- {
- type = (Type)GetBuilder(((AbstractInternalType)tag).TypeDefinition);
- }
- }
- }
- if (null == type)
- {
- throw new InvalidOperationException(string.Format("Could not find a Type for {0}.", tag));
- }
- _typeCache.Add(tag, type);
- }
- return type;
- }
-
- IType GetSimpleEntityType(IArrayType tag)
- {
- return GetSimpleEntityType(tag.GetElementType());
- }
-
- IType GetSimpleEntityType(IType tag)
- {
- if (tag.IsArray)
- {
- return GetSimpleEntityType(((IArrayType)tag).GetElementType());
- }
- return tag;
- }
-
- string GetArrayTypeName(IType tag)
- {
- StringBuilder builder = new StringBuilder();
- GetArrayTypeName(builder, tag);
- return builder.ToString();
- }
-
- void GetArrayTypeName(StringBuilder buffer, IType tag)
- {
- if (tag.IsArray)
- {
- IArrayType array = (IArrayType)tag;
- GetArrayTypeName(buffer, array.GetElementType());
- buffer.Append("[");
- for (int i = 1; i < array.GetArrayRank(); i++)
- {
- buffer.Append(",");
- }
- buffer.Append("]");
- }
- else
- {
- AppendFullTypeName(buffer, tag);
- }
- }
-
- void AppendFullTypeName(StringBuilder buffer, IType type)
- {
- AbstractInternalType internalType = (AbstractInternalType)type;
- AppendFullTypeName(buffer, internalType.TypeDefinition);
- }
-
- void AppendFullTypeName(StringBuilder buffer, TypeDefinition type)
- {
- TypeDefinition parent = type.DeclaringType;
- if (null != parent)
- {
- if (NodeType.Module == parent.NodeType)
- {
- NamespaceDeclaration ns = parent.EnclosingNamespace;
- if (null != ns)
- {
- buffer.Append(ns.Name);
- buffer.Append('.');
- }
- }
- else
- {
- AppendFullTypeName(buffer, parent);
- buffer.Append('+'); // nested type
- }
- }
- buffer.Append(type.Name);
- }
-
- TypeAttributes GetNestedTypeAttributes(TypeMember type)
- {
- return GetExtendedTypeAttributes(GetNestedTypeAccessibility(type), type);
- }
-
- TypeAttributes GetNestedTypeAccessibility(TypeMember type)
- {
- if (type.IsPublic) return TypeAttributes.NestedPublic;
- if (type.IsInternal) return TypeAttributes.NestedAssembly;
- return TypeAttributes.NestedPrivate;
- }
-
- TypeAttributes GetTypeAttributes(TypeMember type)
- {
- TypeAttributes attributes = type.IsPublic ? TypeAttributes.Public : TypeAttributes.NotPublic;
- return GetExtendedTypeAttributes(attributes, type);
- }
-
- TypeAttributes GetExtendedTypeAttributes(TypeAttributes attributes, TypeMember type)
- {
- switch (type.NodeType)
- {
- case NodeType.ClassDefinition:
- {
- attributes |= (TypeAttributes.AnsiClass | TypeAttributes.AutoLayout);
- attributes |= TypeAttributes.Class;
- attributes |= TypeAttributes.BeforeFieldInit;
-
- if (!type.IsTransient)
- {
- attributes |= TypeAttributes.Serializable;
- }
- if (type.IsAbstract)
- {
- attributes |= TypeAttributes.Abstract;
- }
- if (type.IsFinal)
- {
- attributes |= TypeAttributes.Sealed;
- }
- if (((IType)type.Entity).IsValueType)
- {
- attributes |= TypeAttributes.SequentialLayout;
- }
- break;
- }
-
- case NodeType.EnumDefinition:
- {
- attributes |= TypeAttributes.Sealed;
- attributes |= TypeAttributes.Serializable;
- break;
- }
-
- case NodeType.InterfaceDefinition:
- {
- attributes |= (TypeAttributes.Interface | TypeAttributes.Abstract);
- break;
- }
-
- case NodeType.Module:
- {
- attributes |= TypeAttributes.Sealed;
- break;
- }
- }
- return attributes;
- }
-
- PropertyAttributes GetPropertyAttributes(Property property)
- {
- PropertyAttributes attributes = PropertyAttributes.None;
-
- if (property.ExplicitInfo != null)
- {
- attributes |= PropertyAttributes.SpecialName | PropertyAttributes.RTSpecialName;
- }
- return attributes;
- }
-
- MethodAttributes GetMethodAttributesFromTypeMember(TypeMember member)
- {
- MethodAttributes attributes = (MethodAttributes)0;
- if (member.IsPublic)
- {
- attributes = MethodAttributes.Public;
- }
- else if (member.IsProtected)
- {
- attributes = member.IsInternal
- ? MethodAttributes.FamORAssem
- : MethodAttributes.Family;
- }
- else if (member.IsPrivate)
- {
- attributes = MethodAttributes.Private;
- }
- else if (member.IsInternal)
- {
- attributes = MethodAttributes.Assembly;
- }
- if (member.IsStatic)
- {
- attributes |= MethodAttributes.Static;
-
- if (member.Name.StartsWith("op_"))
- {
- attributes |= MethodAttributes.SpecialName;
- }
- }
- if (member.IsFinal)
- {
- attributes |= MethodAttributes.Final;
- }
- if (member.IsAbstract)
- {
- attributes |= (MethodAttributes.Abstract | MethodAttributes.Virtual);
- }
- if (member.IsVirtual || member.IsOverride)
- {
- attributes |= MethodAttributes.Virtual;
- }
- return attributes;
- }
-
- MethodAttributes GetPropertyMethodAttributes(TypeMember property)
- {
- MethodAttributes attributes = MethodAttributes.SpecialName | MethodAttributes.HideBySig;
- attributes |= GetMethodAttributesFromTypeMember(property);
- return attributes;
- }
-
- MethodAttributes GetMethodAttributes(Method method)
- {
- MethodAttributes attributes = MethodAttributes.HideBySig;
- if (method.ExplicitInfo != null)
- {
- attributes |= MethodAttributes.NewSlot;
- }
- if (IsPInvoke(method))
- {
- Debug.Assert(method.IsStatic);
- attributes |= MethodAttributes.PinvokeImpl;
- }
- attributes |= GetMethodAttributesFromTypeMember(method);
- return attributes;
- }
-
- FieldAttributes GetFieldAttributes(Field field)
- {
- FieldAttributes attributes = 0;
- if (field.IsProtected)
- {
- attributes |= FieldAttributes.Family;
- }
- else if (field.IsPublic)
- {
- attributes |= FieldAttributes.Public;
- }
- else if (field.IsPrivate)
- {
- attributes |= FieldAttributes.Private;
- }
- else if (field.IsInternal)
- {
- attributes |= FieldAttributes.Assembly;
- }
- if (field.IsStatic)
- {
- attributes |= FieldAttributes.Static;
- }
- if (field.IsTransient)
- {
- attributes |= FieldAttributes.NotSerialized;
- }
- if (field.IsFinal)
- {
- IField entity = (IField)field.Entity;
- if (entity.IsLiteral)
- {
- attributes |= FieldAttributes.Literal;
- }
- else
- {
- attributes |= FieldAttributes.InitOnly;
- }
- }
- return attributes;
- }
-
- ParameterAttributes GetParameterAttributes(ParameterDeclaration param)
- {
- return ParameterAttributes.None;
- }
-
- void DefineEvent(TypeBuilder typeBuilder, Event node)
- {
- EventBuilder builder = typeBuilder.DefineEvent(node.Name,
- EventAttributes.None,
- GetSystemType(node.Type));
- //MethodAttributes attribs = GetPropertyMethodAttributes(node);
- MethodAttributes baseAttributes = MethodAttributes.SpecialName;
- builder.SetAddOnMethod(DefineMethod(typeBuilder, node.Add, baseAttributes|GetMethodAttributes(node.Add)));
- builder.SetRemoveOnMethod(DefineMethod(typeBuilder, node.Remove, baseAttributes|GetMethodAttributes(node.Remove)));
-
- if (null != node.Raise)
- {
- builder.SetRaiseMethod(DefineMethod(typeBuilder, node.Raise, baseAttributes|GetMethodAttributes(node.Raise)));
- }
-
- SetBuilder(node, builder);
- }
-
- void DefineProperty(TypeBuilder typeBuilder, Property property)
- {
- string name;
- if (property.ExplicitInfo != null)
- {
- name = property.ExplicitInfo.InterfaceType.Name + "." + property.Name;
- }
- else
- {
- name = property.Name;
- }
-
- PropertyBuilder builder = typeBuilder.DefineProperty(name,
- GetPropertyAttributes(property),
- GetSystemType(property.Type),
- GetParameterTypes(property.Parameters));
- Method getter = property.Getter;
- Method setter = property.Setter;
-
- MethodAttributes attribs = GetPropertyMethodAttributes(property);
- if (null != getter)
- {
- MethodBuilder getterBuilder =
- DefineMethod(typeBuilder, getter, attribs);
- builder.SetGetMethod(getterBuilder);
- }
- if (null != setter)
- {
- MethodBuilder setterBuilder =
- DefineMethod(typeBuilder, setter, attribs);
- builder.SetSetMethod(setterBuilder);
- }
- bool isDuckTyped = GetEntity(property).IsDuckTyped;
- if (isDuckTyped)
- {
- builder.SetCustomAttribute(CreateDuckTypedCustomAttribute());
- }
-
- SetBuilder(property, builder);
- }
-
- void DefineField(TypeBuilder typeBuilder, Field field)
- {
- FieldBuilder builder = typeBuilder.DefineField(field.Name,
- GetSystemType(field),
- GetFieldAttributes(field));
- SetBuilder(field, builder);
- }
-
- delegate ParameterBuilder ParameterFactory(int index, System.Reflection.ParameterAttributes attributes, string name);
-
- void DefineParameters(ConstructorBuilder builder, ParameterDeclarationCollection parameters)
- {
- DefineParameters(parameters, new ParameterFactory(builder.DefineParameter));
- }
-
- void DefineParameters(MethodBuilder builder, ParameterDeclarationCollection parameters)
- {
- DefineParameters(parameters, new ParameterFactory(builder.DefineParameter));
- }
-
- void DefineParameters(ParameterDeclarationCollection parameters, ParameterFactory defineParameter)
- {
- int last = parameters.Count - 1;
- for (int i=0; i 0)
- {
- PropertyInfo[] namedProperties;
- object[] propertyValues;
- FieldInfo[] namedFields;
- object[] fieldValues;
- GetNamedValues(namedArgs,
- out namedProperties, out propertyValues,
- out namedFields, out fieldValues);
- return new CustomAttributeBuilder(
- constructorInfo, constructorArgs,
- namedProperties, propertyValues,
- namedFields, fieldValues);
- }
- return new CustomAttributeBuilder(constructorInfo, constructorArgs);
- }
-
- void GetNamedValues(ExpressionPairCollection values,
- out PropertyInfo[] outNamedProperties,
- out object[] outPropertyValues,
- out FieldInfo[] outNamedFields,
- out object[] outFieldValues)
- {
- List namedProperties = new List();
- List propertyValues = new List();
- List namedFields = new List();
- List fieldValues = new List();
- foreach (ExpressionPair pair in values)
- {
- ITypedEntity entity = (ITypedEntity)GetEntity(pair.First);
- object value = GetValue(entity.Type, pair.Second);
- if (EntityType.Property == entity.EntityType)
- {
- namedProperties.Add(GetPropertyInfo(entity));
- propertyValues.Add(value);
- }
- else
- {
- namedFields.Add(GetFieldInfo((IField)entity));
- fieldValues.Add(value);
- }
- }
-
- outNamedProperties = (PropertyInfo[])namedProperties.ToArray(typeof(PropertyInfo));
- outPropertyValues = propertyValues.ToArray();
- outNamedFields = (FieldInfo[])namedFields.ToArray(typeof(FieldInfo));
- outFieldValues = fieldValues.ToArray();
- }
-
- object[] GetValues(IParameter[] targetParameters, ExpressionCollection expressions)
- {
- object[] values = new object[expressions.Count];
- for (int i=0; i 0)
- {
- if (!Path.IsPathRooted(fname))
- {
- fname = ResolveRelative(outputFile, srcFile, fname);
- }
- using (FileStream stream = File.OpenRead(fname))
- {
- //Parameters.DelaySign is ignored.
- return new StrongNameKeyPair(stream);
- }
- }
- return null;
- }
-
- string ResolveRelative(string targetFile, string srcFile, string relativeFile)
- {
- //relative to current directory:
- string fname = Path.GetFullPath(relativeFile);
- if (File.Exists(fname))
- {
- return fname;
- }
-
- //relative to source file:
- if (srcFile != null)
- {
- fname = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(srcFile),
- relativeFile));
- if (File.Exists(fname))
- {
- return fname;
- }
- }
-
- //relative to output assembly:
- if (targetFile != null)
- {
- fname = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(targetFile),
- relativeFile));
- }
- return fname;
- }
-
- Version GetAssemblyVersion()
- {
- string version = GetAssemblyAttributeValue("System.Reflection.AssemblyVersionAttribute");
- if (null == version)
- {
- version = "0.0.0.0";
- }
- /* 1.0.* -- BUILD -- based on days since January 1, 2000
- * 1.0.0.* -- REVISION -- based on seconds since midnight, January 1, 2000, divided by 2 *
- */
- string[] sliced = version.Split('.');
- if (sliced.Length > 2)
- {
- DateTime baseTime = new DateTime(2000, 1, 1);
- TimeSpan mark = (DateTime.Now - baseTime);
- if (sliced[2].StartsWith("*"))
- {
- sliced[2] = Math.Round(mark.TotalDays).ToString();
- }
- if (sliced.Length > 3)
- {
- if (sliced[3].StartsWith("*"))
- {
- sliced[3] = Math.Round(mark.TotalSeconds).ToString();
- }
- }
- version = Boo.Lang.Builtins.join(sliced, ".");
- }
- return new Version(version);
- }
-
- string GetAssemblyAttributeValue(string name)
- {
- Attribute attribute = GetAssemblyAttribute(name);
- if (null != attribute)
- {
- return ((StringLiteralExpression)attribute.Arguments[0]).Value;
- }
- return null;
- }
-
- Attribute GetAssemblyAttribute(string name)
- {
- Attribute[] attributes = _assemblyAttributes.Get(name);
- if (attributes.Length > 0)
- {
- Debug.Assert(1 == attributes.Length);
- return attributes[0];
- }
- return null;
- }
-
- protected override IType GetExpressionType(Expression node)
- {
- IType type = base.GetExpressionType(node);
- if (TypeSystemServices.IsUnknown(type)) throw CompilerErrorFactory.InvalidNode(node);
- return type;
- }
- }
-}
+ }
+
+ override public void OnMemberReferenceExpression(MemberReferenceExpression node)
+ {
+ IEntity tag = TypeSystem.TypeSystemServices.GetEntity(node);
+ switch (tag.EntityType)
+ {
+ case EntityType.Method:
+ {
+ node.Target.Accept(this);
+ break;
+ }
+
+ case EntityType.Field:
+ {
+ EmitLoadField(node.Target, (IField)tag);
+ break;
+ }
+
+ case EntityType.Type:
+ {
+ EmitGetTypeFromHandle(GetSystemType(node));
+ break;
+ }
+
+ default:
+ {
+ NotImplemented(node, tag.ToString());
+ break;
+ }
+ }
+ }
+
+ void LoadAddress(Expression expression)
+ {
+ if (NodeType.SelfLiteralExpression == expression.NodeType)
+ {
+ if (expression.ExpressionType.IsValueType)
+ {
+ _il.Emit(OpCodes.Ldarg_0);
+ return;
+ }
+ }
+
+ IEntity tag = expression.Entity;
+ if (null != tag)
+ {
+ switch (tag.EntityType)
+ {
+ case EntityType.Local:
+ {
+ _il.Emit(OpCodes.Ldloca, ((InternalLocal)tag).LocalBuilder);
+ return;
+ }
+
+ case EntityType.Parameter:
+ {
+ InternalParameter param = (InternalParameter)tag;
+ if (param.Parameter.IsByRef)
+ {
+ LoadParam(param);
+ }
+ else
+ {
+ _il.Emit(OpCodes.Ldarga, param.Index);
+ }
+ return;
+ }
+
+ case EntityType.Field:
+ {
+ IField field = (IField)tag;
+ if (!field.IsLiteral)
+ {
+ EmitLoadFieldAddress(expression, field);
+ return;
+ }
+ break;
+ }
+ }
+ }
+
+ if (IsValueTypeArraySlicing(expression))
+ {
+ SlicingExpression slicing = (SlicingExpression)expression;
+ Visit(slicing.Target);
+ IArrayType arrayType = (IArrayType)PopType();
+ EmitNormalizedArrayIndex(slicing, slicing.Indices[0].Begin);
+ _il.Emit(OpCodes.Ldelema, GetSystemType(arrayType.GetElementType()));
+ }
+ else
+ {
+ // declare local to hold value type
+ Visit(expression);
+ LocalBuilder temp = _il.DeclareLocal(GetSystemType(PopType()));
+ _il.Emit(OpCodes.Stloc, temp);
+ _il.Emit(OpCodes.Ldloca, temp);
+ }
+ }
+
+ bool IsValueTypeArraySlicing(Expression expression)
+ {
+ SlicingExpression slicing = expression as SlicingExpression;
+ if (null != slicing)
+ {
+ IArrayType type = (IArrayType)slicing.Target.ExpressionType;
+ return type.GetElementType().IsValueType;
+ }
+ return false;
+ }
+
+ override public void OnSelfLiteralExpression(SelfLiteralExpression node)
+ {
+ _il.Emit(OpCodes.Ldarg_0);
+ if (node.ExpressionType.IsValueType)
+ {
+ _il.Emit(OpCodes.Ldobj, GetSystemType(node.ExpressionType));
+ }
+ PushType(node.ExpressionType);
+ }
+
+ override public void OnSuperLiteralExpression(SuperLiteralExpression node)
+ {
+ _il.Emit(OpCodes.Ldarg_0);
+ if (node.ExpressionType.IsValueType)
+ {
+ _il.Emit(OpCodes.Ldobj, GetSystemType(node.ExpressionType));
+ }
+ PushType(node.ExpressionType);
+ }
+
+ override public void OnNullLiteralExpression(NullLiteralExpression node)
+ {
+ _il.Emit(OpCodes.Ldnull);
+ PushType(null);
+ }
+
+ override public void OnReferenceExpression(ReferenceExpression node)
+ {
+ IEntity info = TypeSystem.TypeSystemServices.GetEntity(node);
+ switch (info.EntityType)
+ {
+ case EntityType.Local:
+ {
+ InternalLocal local = (InternalLocal)info;
+ LocalBuilder builder = local.LocalBuilder;
+ _il.Emit(OpCodes.Ldloc, builder);
+ PushType(local.Type);
+ break;
+ }
+
+ case EntityType.Parameter:
+ {
+ InternalParameter param = (InternalParameter)info;
+ LoadParam(param);
+
+ if (param.Parameter.IsByRef)
+ {
+ OpCode code = GetLoadRefParamCode(param.Type);
+ if (code.Value == OpCodes.Ldobj.Value)
+ {
+ _il.Emit(code, GetSystemType(param.Type));
+ }
+ else {
+ _il.Emit(code);
+ }
+ }
+ PushType(param.Type);
+ break;
+ }
+
+ case EntityType.Array:
+ case EntityType.Type:
+ {
+ EmitGetTypeFromHandle(GetSystemType(node));
+ break;
+ }
+
+ default:
+ {
+ NotImplemented(node, info.ToString());
+ break;
+ }
+
+ }
+ }
+
+ void LoadParam(InternalParameter param)
+ {
+ int index = param.Index;
+
+ switch (index)
+ {
+ case 0:
+ {
+ _il.Emit(OpCodes.Ldarg_0);
+ break;
+ }
+
+ case 1:
+ {
+ _il.Emit(OpCodes.Ldarg_1);
+ break;
+ }
+
+ case 2:
+ {
+ _il.Emit(OpCodes.Ldarg_2);
+ break;
+ }
+
+ case 3:
+ {
+ _il.Emit(OpCodes.Ldarg_3);
+ break;
+ }
+
+ default:
+ {
+ if (index < 256)
+ {
+ _il.Emit(OpCodes.Ldarg_S, index);
+ }
+ else
+ {
+ _il.Emit(OpCodes.Ldarg, index);
+ }
+ break;
+ }
+ }
+ }
+ void SetLocal(BinaryExpression node, InternalLocal tag, bool leaveValueOnStack)
+ {
+ node.Right.Accept(this); // leaves type on stack
+
+ IType typeOnStack = null;
+
+ if (leaveValueOnStack)
+ {
+ typeOnStack = PeekTypeOnStack();
+ _il.Emit(OpCodes.Dup);
+ }
+ else
+ {
+ typeOnStack = PopType();
+ }
+ EmitAssignment(tag, typeOnStack);
+ }
+
+ void EmitAssignment(InternalLocal tag, IType typeOnStack)
+ {
+ // todo: assignment result must be type on the left in the
+ // case of casting
+ LocalBuilder local = tag.LocalBuilder;
+ EmitCastIfNeeded(tag.Type, typeOnStack);
+ _il.Emit(OpCodes.Stloc, local);
+ }
+
+ void SetField(Node sourceNode, IField field, Expression reference, Expression value, bool leaveValueOnStack)
+ {
+ OpCode opSetField = OpCodes.Stsfld;
+ if (!field.IsStatic)
+ {
+ opSetField = OpCodes.Stfld;
+ if (null != reference)
+ {
+ LoadMemberTarget(
+ ((MemberReferenceExpression)reference).Target,
+ field);
+ }
+ }
+
+ value.Accept(this);
+ EmitCastIfNeeded(field.Type, PopType());
+
+ FieldInfo fi = GetFieldInfo(field);
+ LocalBuilder local = null;
+ if (leaveValueOnStack)
+ {
+ _il.Emit(OpCodes.Dup);
+ local = _il.DeclareLocal(fi.FieldType);
+ _il.Emit(OpCodes.Stloc, local);
+ }
+
+ _il.Emit(opSetField, fi);
+
+ if (leaveValueOnStack)
+ {
+ _il.Emit(OpCodes.Ldloc, local);
+ PushType(field.Type);
+ }
+ }
+
+ void SetProperty(Node sourceNode, IProperty property, Expression reference, Expression value, bool leaveValueOnStack)
+ {
+ OpCode callOpCode = OpCodes.Call;
+
+ MethodInfo setMethod = GetMethodInfo(property.GetSetMethod());
+
+ if (null != reference)
+ {
+ if (!setMethod.IsStatic)
+ {
+ Expression target = ((MemberReferenceExpression)reference).Target;
+ if (setMethod.DeclaringType.IsValueType)
+ {
+ LoadAddress(target);
+ }
+ else
+ {
+ callOpCode = OpCodes.Callvirt;
+ target.Accept(this);
+ PopType();
+ }
+ }
+ }
+
+ value.Accept(this);
+ EmitCastIfNeeded(property.Type, PopType());
+
+ LocalBuilder local = null;
+ if (leaveValueOnStack)
+ {
+ _il.Emit(OpCodes.Dup);
+ local = _il.DeclareLocal(GetSystemType(property.Type));
+ _il.Emit(OpCodes.Stloc, local);
+ }
+
+ _il.EmitCall(callOpCode, setMethod, null);
+
+ if (leaveValueOnStack)
+ {
+ _il.Emit(OpCodes.Ldloc, local);
+ PushType(property.Type);
+ }
+ }
+
+ bool EmitDebugInfo(Node node)
+ {
+ return EmitDebugInfo(node, node);
+ }
+
+ bool EmitDebugInfo(Node startNode, Node endNode)
+ {
+ if (!Parameters.Debug) return false;
+
+ LexicalInfo start = startNode.LexicalInfo;
+ if (!start.IsValid) return false;
+
+ ISymbolDocumentWriter writer = GetDocumentWriter(start.FullPath);
+ if (null == writer) return false;
+
+ try
+ {
+ _il.MarkSequencePoint(writer, start.Line, 0, start.Line+1, 0);
+ }
+ catch (Exception x)
+ {
+ Error(CompilerErrorFactory.InternalError(startNode, x));
+ return false;
+ }
+
+ return true;
+ }
+
+ private ISymbolDocumentWriter GetDocumentWriter(string fname)
+ {
+ ISymbolDocumentWriter writer = GetCachedDocumentWriter(fname);
+ if (null != writer) return writer;
+
+ writer = _moduleBuilder.DefineDocument(
+ fname,
+ Guid.Empty,
+ Guid.Empty,
+ SymDocumentType.Text);
+ _symbolDocWriters.Add(fname, writer);
+
+ return writer;
+ }
+
+ private ISymbolDocumentWriter GetCachedDocumentWriter(string fname)
+ {
+ return (ISymbolDocumentWriter) _symbolDocWriters[fname];
+ }
+
+ bool IsBoolOrInt(IType type)
+ {
+ return TypeSystemServices.BoolType == type ||
+ TypeSystemServices.IntType == type;
+ }
+
+ void PushArguments(IMethodBase entity, ExpressionCollection args)
+ {
+ IParameter[] parameters = entity.GetParameters();
+ for (int i=0; i 1)
+ {
+ type = Array.CreateInstance(GetSystemType(arrayType.GetElementType()), new int[arrayType.GetArrayRank()]).GetType();
+ }
+ else
+ {
+ type = Array.CreateInstance(GetSystemType(arrayType.GetElementType()), 0).GetType();
+ }
+ }
+ }
+ else if (Null.Default == tag)
+ {
+ type = Types.Object;
+ }
+ else
+ {
+ type = (Type)GetBuilder(((AbstractInternalType)tag).TypeDefinition);
+ }
+
+ if (null == type)
+ {
+ throw new InvalidOperationException(string.Format("Could not find a Type for {0}.", tag));
+ }
+
+ _typeCache.Add(tag, type);
+ return type;
+ }
+
+ IType GetSimpleEntityType(IArrayType tag)
+ {
+ return GetSimpleEntityType(tag.GetElementType());
+ }
+
+ IType GetSimpleEntityType(IType tag)
+ {
+ if (tag.IsArray)
+ {
+ return GetSimpleEntityType(((IArrayType)tag).GetElementType());
+ }
+ return tag;
+ }
+
+ string GetArrayTypeName(IType tag)
+ {
+ StringBuilder builder = new StringBuilder();
+ GetArrayTypeName(builder, tag);
+ return builder.ToString();
+ }
+
+ void GetArrayTypeName(StringBuilder buffer, IType tag)
+ {
+ if (tag.IsArray)
+ {
+ IArrayType array = (IArrayType)tag;
+ GetArrayTypeName(buffer, array.GetElementType());
+ buffer.Append("[");
+ for (int i = 1; i < array.GetArrayRank(); i++)
+ {
+ buffer.Append(",");
+ }
+ buffer.Append("]");
+ }
+ else
+ {
+ AppendFullTypeName(buffer, tag);
+ }
+ }
+
+ void AppendFullTypeName(StringBuilder buffer, IType type)
+ {
+ AbstractInternalType internalType = (AbstractInternalType)type;
+ AppendFullTypeName(buffer, internalType.TypeDefinition);
+ }
+
+ void AppendFullTypeName(StringBuilder buffer, TypeDefinition type)
+ {
+ TypeDefinition parent = type.DeclaringType;
+ if (null != parent)
+ {
+ if (NodeType.Module == parent.NodeType)
+ {
+ NamespaceDeclaration ns = parent.EnclosingNamespace;
+ if (null != ns)
+ {
+ buffer.Append(ns.Name);
+ buffer.Append('.');
+ }
+ }
+ else
+ {
+ AppendFullTypeName(buffer, parent);
+ buffer.Append('+'); // nested type
+ }
+ }
+ buffer.Append(type.Name);
+ }
+
+ TypeAttributes GetNestedTypeAttributes(TypeMember type)
+ {
+ return GetExtendedTypeAttributes(GetNestedTypeAccessibility(type), type);
+ }
+
+ TypeAttributes GetNestedTypeAccessibility(TypeMember type)
+ {
+ if (type.IsPublic) return TypeAttributes.NestedPublic;
+ if (type.IsInternal) return TypeAttributes.NestedAssembly;
+ return TypeAttributes.NestedPrivate;
+ }
+
+ TypeAttributes GetTypeAttributes(TypeMember type)
+ {
+ TypeAttributes attributes = type.IsPublic ? TypeAttributes.Public : TypeAttributes.NotPublic;
+ return GetExtendedTypeAttributes(attributes, type);
+ }
+
+ TypeAttributes GetExtendedTypeAttributes(TypeAttributes attributes, TypeMember type)
+ {
+ switch (type.NodeType)
+ {
+ case NodeType.ClassDefinition:
+ {
+ attributes |= (TypeAttributes.AnsiClass | TypeAttributes.AutoLayout);
+ attributes |= TypeAttributes.Class;
+ attributes |= TypeAttributes.BeforeFieldInit;
+
+ if (!type.IsTransient)
+ {
+ attributes |= TypeAttributes.Serializable;
+ }
+ if (type.IsAbstract)
+ {
+ attributes |= TypeAttributes.Abstract;
+ }
+ if (type.IsFinal)
+ {
+ attributes |= TypeAttributes.Sealed;
+ }
+ if (((IType)type.Entity).IsValueType)
+ {
+ attributes |= TypeAttributes.SequentialLayout;
+ }
+ break;
+ }
+
+ case NodeType.EnumDefinition:
+ {
+ attributes |= TypeAttributes.Sealed;
+ attributes |= TypeAttributes.Serializable;
+ break;
+ }
+
+ case NodeType.InterfaceDefinition:
+ {
+ attributes |= (TypeAttributes.Interface | TypeAttributes.Abstract);
+ break;
+ }
+
+ case NodeType.Module:
+ {
+ attributes |= TypeAttributes.Sealed;
+ break;
+ }
+ }
+ return attributes;
+ }
+
+ PropertyAttributes GetPropertyAttributes(Property property)
+ {
+ PropertyAttributes attributes = PropertyAttributes.None;
+
+ if (property.ExplicitInfo != null)
+ {
+ attributes |= PropertyAttributes.SpecialName | PropertyAttributes.RTSpecialName;
+ }
+ return attributes;
+ }
+
+ MethodAttributes GetMethodAttributesFromTypeMember(TypeMember member)
+ {
+ MethodAttributes attributes = (MethodAttributes)0;
+ if (member.IsPublic)
+ {
+ attributes = MethodAttributes.Public;
+ }
+ else if (member.IsProtected)
+ {
+ attributes = member.IsInternal
+ ? MethodAttributes.FamORAssem
+ : MethodAttributes.Family;
+ }
+ else if (member.IsPrivate)
+ {
+ attributes = MethodAttributes.Private;
+ }
+ else if (member.IsInternal)
+ {
+ attributes = MethodAttributes.Assembly;
+ }
+ if (member.IsStatic)
+ {
+ attributes |= MethodAttributes.Static;
+
+ if (member.Name.StartsWith("op_"))
+ {
+ attributes |= MethodAttributes.SpecialName;
+ }
+ }
+ if (member.IsFinal)
+ {
+ attributes |= MethodAttributes.Final;
+ }
+ if (member.IsAbstract)
+ {
+ attributes |= (MethodAttributes.Abstract | MethodAttributes.Virtual);
+ }
+ if (member.IsVirtual || member.IsOverride)
+ {
+ attributes |= MethodAttributes.Virtual;
+ }
+ return attributes;
+ }
+
+ MethodAttributes GetPropertyMethodAttributes(TypeMember property)
+ {
+ MethodAttributes attributes = MethodAttributes.SpecialName | MethodAttributes.HideBySig;
+ attributes |= GetMethodAttributesFromTypeMember(property);
+ return attributes;
+ }
+
+ MethodAttributes GetMethodAttributes(Method method)
+ {
+ MethodAttributes attributes = MethodAttributes.HideBySig;
+ if (method.ExplicitInfo != null)
+ {
+ attributes |= MethodAttributes.NewSlot;
+ }
+ if (IsPInvoke(method))
+ {
+ Debug.Assert(method.IsStatic);
+ attributes |= MethodAttributes.PinvokeImpl;
+ }
+ attributes |= GetMethodAttributesFromTypeMember(method);
+ return attributes;
+ }
+
+ FieldAttributes GetFieldAttributes(Field field)
+ {
+ FieldAttributes attributes = 0;
+ if (field.IsProtected)
+ {
+ attributes |= FieldAttributes.Family;
+ }
+ else if (field.IsPublic)
+ {
+ attributes |= FieldAttributes.Public;
+ }
+ else if (field.IsPrivate)
+ {
+ attributes |= FieldAttributes.Private;
+ }
+ else if (field.IsInternal)
+ {
+ attributes |= FieldAttributes.Assembly;
+ }
+ if (field.IsStatic)
+ {
+ attributes |= FieldAttributes.Static;
+ }
+ if (field.IsTransient)
+ {
+ attributes |= FieldAttributes.NotSerialized;
+ }
+ if (field.IsFinal)
+ {
+ IField entity = (IField)field.Entity;
+ if (entity.IsLiteral)
+ {
+ attributes |= FieldAttributes.Literal;
+ }
+ else
+ {
+ attributes |= FieldAttributes.InitOnly;
+ }
+ }
+ return attributes;
+ }
+
+ ParameterAttributes GetParameterAttributes(ParameterDeclaration param)
+ {
+ return ParameterAttributes.None;
+ }
+
+ void DefineEvent(TypeBuilder typeBuilder, Event node)
+ {
+ EventBuilder builder = typeBuilder.DefineEvent(node.Name,
+ EventAttributes.None,
+ GetSystemType(node.Type));
+ //MethodAttributes attribs = GetPropertyMethodAttributes(node);
+ MethodAttributes baseAttributes = MethodAttributes.SpecialName;
+ builder.SetAddOnMethod(DefineMethod(typeBuilder, node.Add, baseAttributes|GetMethodAttributes(node.Add)));
+ builder.SetRemoveOnMethod(DefineMethod(typeBuilder, node.Remove, baseAttributes|GetMethodAttributes(node.Remove)));
+
+ if (null != node.Raise)
+ {
+ builder.SetRaiseMethod(DefineMethod(typeBuilder, node.Raise, baseAttributes|GetMethodAttributes(node.Raise)));
+ }
+
+ SetBuilder(node, builder);
+ }
+
+ void DefineProperty(TypeBuilder typeBuilder, Property property)
+ {
+ string name;
+ if (property.ExplicitInfo != null)
+ {
+ name = property.ExplicitInfo.InterfaceType.Name + "." + property.Name;
+ }
+ else
+ {
+ name = property.Name;
+ }
+
+ PropertyBuilder builder = typeBuilder.DefineProperty(name,
+ GetPropertyAttributes(property),
+ GetSystemType(property.Type),
+ GetParameterTypes(property.Parameters));
+ Method getter = property.Getter;
+ Method setter = property.Setter;
+
+ MethodAttributes attribs = GetPropertyMethodAttributes(property);
+ if (null != getter)
+ {
+ MethodBuilder getterBuilder =
+ DefineMethod(typeBuilder, getter, attribs);
+ builder.SetGetMethod(getterBuilder);
+ }
+ if (null != setter)
+ {
+ MethodBuilder setterBuilder =
+ DefineMethod(typeBuilder, setter, attribs);
+ builder.SetSetMethod(setterBuilder);
+ }
+ bool isDuckTyped = GetEntity(property).IsDuckTyped;
+ if (isDuckTyped)
+ {
+ builder.SetCustomAttribute(CreateDuckTypedCustomAttribute());
+ }
+
+ SetBuilder(property, builder);
+ }
+
+ void DefineField(TypeBuilder typeBuilder, Field field)
+ {
+ FieldBuilder builder = typeBuilder.DefineField(field.Name,
+ GetSystemType(field),
+ GetFieldAttributes(field));
+ SetBuilder(field, builder);
+ }
+
+ delegate ParameterBuilder ParameterFactory(int index, System.Reflection.ParameterAttributes attributes, string name);
+
+ void DefineParameters(ConstructorBuilder builder, ParameterDeclarationCollection parameters)
+ {
+ DefineParameters(parameters, new ParameterFactory(builder.DefineParameter));
+ }
+
+ void DefineParameters(MethodBuilder builder, ParameterDeclarationCollection parameters)
+ {
+ DefineParameters(parameters, new ParameterFactory(builder.DefineParameter));
+ }
+
+ void DefineParameters(ParameterDeclarationCollection parameters, ParameterFactory defineParameter)
+ {
+ int last = parameters.Count - 1;
+ for (int i=0; i 0)
+ {
+ PropertyInfo[] namedProperties;
+ object[] propertyValues;
+ FieldInfo[] namedFields;
+ object[] fieldValues;
+ GetNamedValues(namedArgs,
+ out namedProperties, out propertyValues,
+ out namedFields, out fieldValues);
+ return new CustomAttributeBuilder(
+ constructorInfo, constructorArgs,
+ namedProperties, propertyValues,
+ namedFields, fieldValues);
+ }
+ return new CustomAttributeBuilder(constructorInfo, constructorArgs);
+ }
+
+ void GetNamedValues(ExpressionPairCollection values,
+ out PropertyInfo[] outNamedProperties,
+ out object[] outPropertyValues,
+ out FieldInfo[] outNamedFields,
+ out object[] outFieldValues)
+ {
+ List namedProperties = new List();
+ List propertyValues = new List();
+ List namedFields = new List();
+ List fieldValues = new List();
+ foreach (ExpressionPair pair in values)
+ {
+ ITypedEntity entity = (ITypedEntity)GetEntity(pair.First);
+ object value = GetValue(entity.Type, pair.Second);
+ if (EntityType.Property == entity.EntityType)
+ {
+ namedProperties.Add(GetPropertyInfo(entity));
+ propertyValues.Add(value);
+ }
+ else
+ {
+ namedFields.Add(GetFieldInfo((IField)entity));
+ fieldValues.Add(value);
+ }
+ }
+
+ outNamedProperties = (PropertyInfo[])namedProperties.ToArray(typeof(PropertyInfo));
+ outPropertyValues = propertyValues.ToArray();
+ outNamedFields = (FieldInfo[])namedFields.ToArray(typeof(FieldInfo));
+ outFieldValues = fieldValues.ToArray();
+ }
+
+ object[] GetValues(IParameter[] targetParameters, ExpressionCollection expressions)
+ {
+ object[] values = new object[expressions.Count];
+ for (int i=0; i 0)
+ {
+ if (!Path.IsPathRooted(fname))
+ {
+ fname = ResolveRelative(outputFile, srcFile, fname);
+ }
+ using (FileStream stream = File.OpenRead(fname))
+ {
+ //Parameters.DelaySign is ignored.
+ return new StrongNameKeyPair(stream);
+ }
+ }
+ return null;
+ }
+
+ string ResolveRelative(string targetFile, string srcFile, string relativeFile)
+ {
+ //relative to current directory:
+ string fname = Path.GetFullPath(relativeFile);
+ if (File.Exists(fname))
+ {
+ return fname;
+ }
+
+ //relative to source file:
+ if (srcFile != null)
+ {
+ fname = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(srcFile),
+ relativeFile));
+ if (File.Exists(fname))
+ {
+ return fname;
+ }
+ }
+
+ //relative to output assembly:
+ if (targetFile != null)
+ {
+ fname = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(targetFile),
+ relativeFile));
+ }
+ return fname;
+ }
+
+ Version GetAssemblyVersion()
+ {
+ string version = GetAssemblyAttributeValue("System.Reflection.AssemblyVersionAttribute");
+ if (null == version)
+ {
+ version = "0.0.0.0";
+ }
+ /* 1.0.* -- BUILD -- based on days since January 1, 2000
+ * 1.0.0.* -- REVISION -- based on seconds since midnight, January 1, 2000, divided by 2 *
+ */
+ string[] sliced = version.Split('.');
+ if (sliced.Length > 2)
+ {
+ DateTime baseTime = new DateTime(2000, 1, 1);
+ TimeSpan mark = (DateTime.Now - baseTime);
+ if (sliced[2].StartsWith("*"))
+ {
+ sliced[2] = Math.Round(mark.TotalDays).ToString();
+ }
+ if (sliced.Length > 3)
+ {
+ if (sliced[3].StartsWith("*"))
+ {
+ sliced[3] = Math.Round(mark.TotalSeconds).ToString();
+ }
+ }
+ version = Boo.Lang.Builtins.join(sliced, ".");
+ }
+ return new Version(version);
+ }
+
+ string GetAssemblyAttributeValue(string name)
+ {
+ Attribute attribute = GetAssemblyAttribute(name);
+ if (null != attribute)
+ {
+ return ((StringLiteralExpression)attribute.Arguments[0]).Value;
+ }
+ return null;
+ }
+
+ Attribute GetAssemblyAttribute(string name)
+ {
+ Attribute[] attributes = _assemblyAttributes.Get(name);
+ if (attributes.Length > 0)
+ {
+ Debug.Assert(1 == attributes.Length);
+ return attributes[0];
+ }
+ return null;
+ }
+
+ protected override IType GetExpressionType(Expression node)
+ {
+ IType type = base.GetExpressionType(node);
+ if (TypeSystemServices.IsUnknown(type)) throw CompilerErrorFactory.InvalidNode(node);
+ return type;
+ }
+ }
+}
Index: src/Boo.Lang.Compiler/Steps/ProcessMethodBodies.cs
===================================================================
--- src/Boo.Lang.Compiler/Steps/ProcessMethodBodies.cs (revision 2352)
+++ src/Boo.Lang.Compiler/Steps/ProcessMethodBodies.cs (working copy)
@@ -2032,8 +2032,7 @@
return;
}
- IGenericTypeDefinition typeDef = (IGenericTypeDefinition) node.Target.Entity;
- IType genericType = typeDef.MakeGenericType(GetGenericArguments(node));
+ IType genericType = ((IType)node.Target.Entity).GenericTypeDefinitionInfo.MakeGenericType(GetGenericArguments(node));
Bind(node, genericType);
BindExpressionType(node, this.TypeSystemServices.TypeType);
@@ -2053,10 +2052,13 @@
CompilerError CheckGenericReferenceExpression(GenericReferenceExpression node)
{
IEntity entity = node.Target.Entity;
- IGenericTypeDefinition typeDef = entity as IGenericTypeDefinition;
- if (typeDef == null) return CompilerErrorFactory.NotAGenericDefinition(AstUtil.GetMemberAnchor(node.Target), entity.FullName);
+ IType type = entity as IType;
+ if (type == null || type.GenericTypeDefinitionInfo == null)
+ {
+ return CompilerErrorFactory.NotAGenericDefinition(AstUtil.GetMemberAnchor(node.Target), entity.FullName);
+ }
- IGenericParameter[] parameters = typeDef.GetGenericParameters();
+ IGenericParameter[] parameters = type.GenericTypeDefinitionInfo.GenericParameters;
if (parameters.Length != node.GenericArguments.Count) return CompilerErrorFactory.GenericDefinitionArgumentCount(AstUtil.GetMemberAnchor(node.Target), entity.FullName, parameters.Length);
return null;
@@ -2300,6 +2302,7 @@
Error(node);
return;
}
+
BindExpressionType(node, GetInferredType(memberInfo));
}
else
Index: src/Boo.Lang.Compiler/TypeSystem/AbstractInternalType.cs
===================================================================
--- src/Boo.Lang.Compiler/TypeSystem/AbstractInternalType.cs (revision 2352)
+++ src/Boo.Lang.Compiler/TypeSystem/AbstractInternalType.cs (working copy)
@@ -1,378 +1,388 @@
-#region license
-// Copyright (c) 2004, Rodrigo B. de Oliveira (rbo@acm.org)
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without modification,
-// are permitted provided that the following conditions are met:
-//
-// * Redistributions of source code must retain the above copyright notice,
-// this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above copyright notice,
-// this list of conditions and the following disclaimer in the documentation
-// and/or other materials provided with the distribution.
-// * Neither the name of Rodrigo B. de Oliveira nor the names of its
-// contributors may be used to endorse or promote products derived from this
-// software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#endregion
-
-namespace Boo.Lang.Compiler.TypeSystem
-{
- using System;
- using System.Collections;
- using System.Reflection;
- using Boo.Lang.Compiler.Ast;
- using Attribute = Boo.Lang.Compiler.Ast.Attribute;
-
- public abstract class AbstractInternalType : IInternalEntity, IType, INamespace
- {
- protected TypeSystemServices _typeSystemServices;
-
- protected TypeDefinition _typeDefinition;
-
- protected IType[] _interfaces;
-
- protected INamespace _parentNamespace;
-
- protected Type _generatedType;
-
- protected AbstractInternalType(TypeSystemServices typeSystemServices, TypeDefinition typeDefinition)
- {
- _typeSystemServices = typeSystemServices;
- _typeDefinition = typeDefinition;
- }
-
- public string FullName
- {
- get
- {
- return _typeDefinition.FullName;
- }
- }
-
- public string Name
- {
- get
- {
- return _typeDefinition.Name;
- }
- }
-
- public Node Node
- {
- get
- {
- return _typeDefinition;
- }
- }
-
- public IType NestingType
- {
- get
- {
- return _typeDefinition.ParentNode.Entity as IType;
- }
- }
-
- public virtual INamespace ParentNamespace
- {
- get
- {
- if (null == _parentNamespace)
- {
- _parentNamespace = (INamespace)TypeSystemServices.GetEntity(_typeDefinition.ParentNode);
- }
- return _parentNamespace;
- }
- }
-
- public virtual bool Resolve(List targetList, string name, EntityType flags)
- {
- bool found = false;
-
- foreach (IEntity entity in GetMembers())
- {
- if (entity.Name == name && NameResolutionService.IsFlagSet(flags, entity.EntityType))
- {
- targetList.AddUnique(entity);
- found = true;
- }
- }
-
- return found;
- }
-
- public virtual IType BaseType
- {
- get
- {
- return null;
- }
- }
-
- public TypeDefinition TypeDefinition
- {
- get
- {
- return _typeDefinition;
- }
- }
-
- public IType Type
- {
- get
- {
- return this;
- }
- }
-
- public bool IsByRef
- {
- get
- {
- return false;
- }
- }
-
- public IType GetElementType()
- {
- return null;
- }
-
- public bool IsClass
- {
- get
- {
- return NodeType.ClassDefinition == _typeDefinition.NodeType;
- }
- }
-
- public bool IsAbstract
- {
- get
- {
- return _typeDefinition.IsAbstract;
- }
- }
-
- virtual public bool IsFinal
- {
- get
- {
- return _typeDefinition.IsFinal || IsValueType;
- }
- }
-
- public bool IsInterface
- {
- get
- {
- return NodeType.InterfaceDefinition == _typeDefinition.NodeType;
- }
- }
-
- public bool IsEnum
- {
- get
- {
- return NodeType.EnumDefinition == _typeDefinition.NodeType;
- }
- }
-
- virtual public bool IsValueType
- {
- get
- {
- return false;
- }
- }
-
- public bool IsArray
- {
- get
- {
- return false;
- }
- }
-
- public virtual int GetTypeDepth()
- {
- return 1;
- }
-
- public IEntity GetDefaultMember()
- {
- IType defaultMemberAttribute = _typeSystemServices.Map(Types.DefaultMemberAttribute);
- foreach (Attribute attribute in _typeDefinition.Attributes)
- {
- IConstructor tag = TypeSystemServices.GetEntity(attribute) as IConstructor;
- if (null != tag)
- {
- if (defaultMemberAttribute == tag.DeclaringType)
- {
- StringLiteralExpression memberName = attribute.Arguments[0] as StringLiteralExpression;
- if (null != memberName)
- {
- List buffer = new List();
- Resolve(buffer, memberName.Value, EntityType.Any);
- return NameResolutionService.GetEntityFromList(buffer);
- }
- }
- }
- }
- if (_typeDefinition.BaseTypes.Count > 0)
- {
- List buffer = new List();
-
- foreach (TypeReference baseType in _typeDefinition.BaseTypes)
- {
- IType tag = TypeSystemServices.GetType(baseType);
- IEntity defaultMember = tag.GetDefaultMember();
- if (defaultMember != null)
- {
- if (tag.IsInterface)
- {
- buffer.AddUnique(defaultMember);
- }
- else //non-interface base class trumps interfaces
- {
- return defaultMember;
- }
- }
- }
- return NameResolutionService.GetEntityFromList(buffer);
- }
- return null;
- }
-
- public virtual EntityType EntityType
- {
- get
- {
- return EntityType.Type;
- }
- }
-
- public virtual bool IsSubclassOf(IType other)
- {
- return false;
- }
-
- public virtual bool IsAssignableFrom(IType other)
- {
- return this == other ||
- (!this.IsValueType && Null.Default == other) ||
- other.IsSubclassOf(this);
- }
-
- public virtual IConstructor[] GetConstructors()
- {
- return new IConstructor[0];
- }
-
- public IType[] GetInterfaces()
- {
- if (null == _interfaces)
- {
- List buffer = new List();
-
- foreach (TypeReference baseType in _typeDefinition.BaseTypes)
- {
- IType tag = TypeSystemServices.GetType(baseType);
- if (tag.IsInterface)
- {
- buffer.AddUnique(tag);
- }
- }
-
- _interfaces = (IType[])buffer.ToArray(typeof(IType));
- }
- return _interfaces;
- }
-
- public virtual IEntity[] GetMembers()
- {
- ArrayList buffer = new ArrayList();
- foreach (TypeMember member in _typeDefinition.Members)
- {
- buffer.Add(GetMemberEntity(member));
- }
- return (IEntity[])buffer.ToArray(typeof(IEntity));
- }
-
- private IEntity GetMemberEntity(TypeMember member)
- {
- if (null == member.Entity)
- {
- member.Entity = CreateEntity(member);
- }
- return member.Entity;
- }
-
- private IEntity CreateEntity(TypeMember member)
- {
- switch (member.NodeType)
- {
- case NodeType.Field:
- {
- return new InternalField((Field)member);
- }
-
- case NodeType.EnumMember:
- {
- return new InternalEnumMember(_typeSystemServices, (EnumMember)member);
- }
-
- case NodeType.Method:
- {
- return new InternalMethod(_typeSystemServices, (Method)member);
- }
-
- case NodeType.Constructor:
- {
- return new InternalConstructor(_typeSystemServices, (Constructor)member);
- }
-
- case NodeType.Property:
- {
- return new InternalProperty(_typeSystemServices, (Property)member);
- }
-
- case NodeType.Event:
- {
- return new InternalEvent(_typeSystemServices, (Event)member);
- }
- }
- throw new ArgumentException("Member type not supported: " + member);
- }
-
- public Type GeneratedType
- {
- get
- {
- return _generatedType;
- }
-
- set
- {
- _generatedType = value;
- }
- }
-
- override public string ToString()
- {
- return FullName;
- }
- }
-
-}
+#region license
+// Copyright (c) 2004, Rodrigo B. de Oliveira (rbo@acm.org)
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+// * Neither the name of Rodrigo B. de Oliveira nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#endregion
+
+namespace Boo.Lang.Compiler.TypeSystem
+{
+ using System;
+ using System.Collections;
+ using System.Reflection;
+ using Boo.Lang.Compiler.Ast;
+ using Attribute = Boo.Lang.Compiler.Ast.Attribute;
+
+ public abstract class AbstractInternalType : IInternalEntity, IType, INamespace
+ {
+ protected TypeSystemServices _typeSystemServices;
+
+ protected TypeDefinition _typeDefinition;
+
+ protected IType[] _interfaces;
+
+ protected INamespace _parentNamespace;
+
+ protected Type _generatedType;
+
+ protected AbstractInternalType(TypeSystemServices typeSystemServices, TypeDefinition typeDefinition)
+ {
+ _typeSystemServices = typeSystemServices;
+ _typeDefinition = typeDefinition;
+ }
+
+ public string FullName
+ {
+ get
+ {
+ return _typeDefinition.FullName;
+ }
+ }
+
+ public string Name
+ {
+ get
+ {
+ return _typeDefinition.Name;
+ }
+ }
+
+ public Node Node
+ {
+ get
+ {
+ return _typeDefinition;
+ }
+ }
+
+ public IType NestingType
+ {
+ get
+ {
+ return _typeDefinition.ParentNode.Entity as IType;
+ }
+ }
+
+ public virtual INamespace ParentNamespace
+ {
+ get
+ {
+ if (null == _parentNamespace)
+ {
+ _parentNamespace = (INamespace)TypeSystemServices.GetEntity(_typeDefinition.ParentNode);
+ }
+ return _parentNamespace;
+ }
+ }
+
+ public virtual bool Resolve(List targetList, string name, EntityType flags)
+ {
+ bool found = false;
+
+ foreach (IEntity entity in GetMembers())
+ {
+ if (entity.Name == name && NameResolutionService.IsFlagSet(flags, entity.EntityType))
+ {
+ targetList.AddUnique(entity);
+ found = true;
+ }
+ }
+
+ return found;
+ }
+
+ public virtual IType BaseType
+ {
+ get
+ {
+ return null;
+ }
+ }
+
+ public TypeDefinition TypeDefinition
+ {
+ get
+ {
+ return _typeDefinition;
+ }
+ }
+
+ public IType Type
+ {
+ get
+ {
+ return this;
+ }
+ }
+
+ public bool IsByRef
+ {
+ get
+ {
+ return false;
+ }
+ }
+
+ public IType GetElementType()
+ {
+ return null;
+ }
+
+ public bool IsClass
+ {
+ get
+ {
+ return NodeType.ClassDefinition == _typeDefinition.NodeType;
+ }
+ }
+
+ public bool IsAbstract
+ {
+ get
+ {
+ return _typeDefinition.IsAbstract;
+ }
+ }
+
+ virtual public bool IsFinal
+ {
+ get
+ {
+ return _typeDefinition.IsFinal || IsValueType;
+ }
+ }
+
+ public bool IsInterface
+ {
+ get
+ {
+ return NodeType.InterfaceDefinition == _typeDefinition.NodeType;
+ }
+ }
+
+ public bool IsEnum
+ {
+ get
+ {
+ return NodeType.EnumDefinition == _typeDefinition.NodeType;
+ }
+ }
+
+ virtual public bool IsValueType
+ {
+ get
+ {
+ return false;
+ }
+ }
+
+ public bool IsArray
+ {
+ get
+ {
+ return false;
+ }
+ }
+
+ public virtual int GetTypeDepth()
+ {
+ return 1;
+ }
+
+ public IEntity GetDefaultMember()
+ {
+ IType defaultMemberAttribute = _typeSystemServices.Map(Types.DefaultMemberAttribute);
+ foreach (Attribute attribute in _typeDefinition.Attributes)
+ {
+ IConstructor tag = TypeSystemServices.GetEntity(attribute) as IConstructor;
+ if (null != tag)
+ {
+ if (defaultMemberAttribute == tag.DeclaringType)
+ {
+ StringLiteralExpression memberName = attribute.Arguments[0] as StringLiteralExpression;
+ if (null != memberName)
+ {
+ List buffer = new List();
+ Resolve(buffer, memberName.Value, EntityType.Any);
+ return NameResolutionService.GetEntityFromList(buffer);
+ }
+ }
+ }
+ }
+ if (_typeDefinition.BaseTypes.Count > 0)
+ {
+ List buffer = new List();
+
+ foreach (TypeReference baseType in _typeDefinition.BaseTypes)
+ {
+ IType tag = TypeSystemServices.GetType(baseType);
+ IEntity defaultMember = tag.GetDefaultMember();
+ if (defaultMember != null)
+ {
+ if (tag.IsInterface)
+ {
+ buffer.AddUnique(defaultMember);
+ }
+ else //non-interface base class trumps interfaces
+ {
+ return defaultMember;
+ }
+ }
+ }
+ return NameResolutionService.GetEntityFromList(buffer);
+ }
+ return null;
+ }
+
+ public virtual EntityType EntityType
+ {
+ get
+ {
+ return EntityType.Type;
+ }
+ }
+
+ public virtual bool IsSubclassOf(IType other)
+ {
+ return false;
+ }
+
+ public virtual bool IsAssignableFrom(IType other)
+ {
+ return this == other ||
+ (!this.IsValueType && Null.Default == other) ||
+ other.IsSubclassOf(this);
+ }
+
+ public virtual IConstructor[] GetConstructors()
+ {
+ return new IConstructor[0];
+ }
+
+ public IType[] GetInterfaces()
+ {
+ if (null == _interfaces)
+ {
+ List buffer = new List();
+
+ foreach (TypeReference baseType in _typeDefinition.BaseTypes)
+ {
+ IType tag = TypeSystemServices.GetType(baseType);
+ if (tag.IsInterface)
+ {
+ buffer.AddUnique(tag);
+ }
+ }
+
+ _interfaces = (IType[])buffer.ToArray(typeof(IType));
+ }
+ return _interfaces;
+ }
+
+ public virtual IEntity[] GetMembers()
+ {
+ ArrayList buffer = new ArrayList();
+ foreach (TypeMember member in _typeDefinition.Members)
+ {
+ buffer.Add(GetMemberEntity(member));
+ }
+ return (IEntity[])buffer.ToArray(typeof(IEntity));
+ }
+
+ private IEntity GetMemberEntity(TypeMember member)
+ {
+ if (null == member.Entity)
+ {
+ member.Entity = CreateEntity(member);
+ }
+ return member.Entity;
+ }
+
+ private IEntity CreateEntity(TypeMember member)
+ {
+ switch (member.NodeType)
+ {
+ case NodeType.Field:
+ {
+ return new InternalField((Field)member);
+ }
+
+ case NodeType.EnumMember:
+ {
+ return new InternalEnumMember(_typeSystemServices, (EnumMember)member);
+ }
+
+ case NodeType.Method:
+ {
+ return new InternalMethod(_typeSystemServices, (Method)member);
+ }
+
+ case NodeType.Constructor:
+ {
+ return new InternalConstructor(_typeSystemServices, (Constructor)member);
+ }
+
+ case NodeType.Property:
+ {
+ return new InternalProperty(_typeSystemServices, (Property)member);
+ }
+
+ case NodeType.Event:
+ {
+ return new InternalEvent(_typeSystemServices, (Event)member);
+ }
+ }
+ throw new ArgumentException("Member type not supported: " + member);
+ }
+
+ public Type GeneratedType
+ {
+ get
+ {
+ return _generatedType;
+ }
+
+ set
+ {
+ _generatedType = value;
+ }
+ }
+
+ override public string ToString()
+ {
+ return FullName;
+ }
+
+ IGenericTypeDefinitionInfo IType.GenericTypeDefinitionInfo
+ {
+ get { return null; }
+ }
+
+ IGenericTypeInfo IType.GenericTypeInfo
+ {
+ get { return null; }
+ }
+ }
+
+}
Index: src/Boo.Lang.Compiler/TypeSystem/ArrayType.cs
===================================================================
--- src/Boo.Lang.Compiler/TypeSystem/ArrayType.cs (revision 2352)
+++ src/Boo.Lang.Compiler/TypeSystem/ArrayType.cs (working copy)
@@ -1,246 +1,256 @@
-#region license
-// Copyright (c) 2004, Rodrigo B. de Oliveira (rbo@acm.org)
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without modification,
-// are permitted provided that the following conditions are met:
-//
-// * Redistributions of source code must retain the above copyright notice,
-// this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above copyright notice,
-// this list of conditions and the following disclaimer in the documentation
-// and/or other materials provided with the distribution.
-// * Neither the name of Rodrigo B. de Oliveira nor the names of its
-// contributors may be used to endorse or promote products derived from this
-// software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#endregion
-
-namespace Boo.Lang.Compiler.TypeSystem
-{
- public class ArrayType : IArrayType
- {
- IType _elementType;
-
- IType _array;
-
- int _rank;
-
- public ArrayType(TypeSystemServices tagManager, IType elementType)
- {
- _array = tagManager.ArrayType;
- _elementType = elementType;
- _rank = 1;
- }
-
- public ArrayType(TypeSystemServices tagManager, IType elementType, int rank)
- {
- _array = tagManager.ArrayType;
- _elementType = elementType;
- _rank = rank;
- }
-
-
- public string Name
- {
- get
- {
- if (_rank > 1)
- {
- return "(" + _elementType.ToString() + ", " + _rank + ")";
- }
- return "(" + _elementType.ToString() + ")";
- }
- }
-
- public EntityType EntityType
- {
- get
- {
- return EntityType.Array;
- }
- }
-
- public string FullName
- {
- get
- {
- return Name;
- }
- }
-
- public IType Type
- {
- get
- {
- return this;
- }
- }
-
- public bool IsFinal
- {
- get
- {
- return true;
- }
- }
-
- public bool IsByRef
- {
- get
- {
- return false;
- }
- }
-
- public bool IsClass
- {
- get
- {
- return false;
- }
- }
-
- public bool IsInterface
- {
- get
- {
- return false;
- }
- }
-
- public bool IsAbstract
- {
- get
- {
- return false;
- }
- }
-
- public bool IsEnum
- {
- get
- {
- return false;
- }
- }
-
- public bool IsValueType
- {
- get
- {
- return false;
- }
- }
-
- public bool IsArray
- {
- get
- {
- return true;
- }
- }
-
- public int GetTypeDepth()
- {
- return 2;
- }
-
- public int GetArrayRank()
- {
- return _rank;
- }
-
- public IType GetElementType()
- {
- return _elementType;
- }
-
- public IType BaseType
- {
- get
- {
- return _array;
- }
- }
-
- public IEntity GetDefaultMember()
- {
- return null;
- }
-
- public virtual bool IsSubclassOf(IType other)
- {
- return other.IsAssignableFrom(_array);
- }
-
- public virtual bool IsAssignableFrom(IType other)
- {
- if (other == this || other == Null.Default)
- {
- return true;
- }
-
- if (other.IsArray)
- {
- IArrayType otherArray = (IArrayType)other;
-
- if (otherArray.GetArrayRank() != _rank)
- {
- return false;
- }
-
- IType otherEntityType = otherArray.GetElementType();
- if (_elementType.IsValueType || otherEntityType.IsValueType)
- {
- return _elementType == otherEntityType;
- }
- return _elementType.IsAssignableFrom(otherEntityType);
- }
- return false;
- }
-
- public IConstructor[] GetConstructors()
- {
- return new IConstructor[0];
- }
-
- public IType[] GetInterfaces()
- {
- return null;
- }
-
- public IEntity[] GetMembers()
- {
- return _array.GetMembers();
- }
-
- public INamespace ParentNamespace
- {
- get
- {
- return _array.ParentNamespace;
- }
- }
-
- public bool Resolve(List targetList, string name, EntityType flags)
- {
- return _array.Resolve(targetList, name, flags);
- }
-
- override public string ToString()
- {
- return Name;
- }
- }
-}
+#region license
+// Copyright (c) 2004, Rodrigo B. de Oliveira (rbo@acm.org)
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+// * Neither the name of Rodrigo B. de Oliveira nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#endregion
+
+namespace Boo.Lang.Compiler.TypeSystem
+{
+ public class ArrayType : IArrayType
+ {
+ IType _elementType;
+
+ IType _array;
+
+ int _rank;
+
+ public ArrayType(TypeSystemServices tagManager, IType elementType)
+ {
+ _array = tagManager.ArrayType;
+ _elementType = elementType;
+ _rank = 1;
+ }
+
+ public ArrayType(TypeSystemServices tagManager, IType elementType, int rank)
+ {
+ _array = tagManager.ArrayType;
+ _elementType = elementType;
+ _rank = rank;
+ }
+
+
+ public string Name
+ {
+ get
+ {
+ if (_rank > 1)
+ {
+ return "(" + _elementType.ToString() + ", " + _rank + ")";
+ }
+ return "(" + _elementType.ToString() + ")";
+ }
+ }
+
+ public EntityType EntityType
+ {
+ get
+ {
+ return EntityType.Array;
+ }
+ }
+
+ public string FullName
+ {
+ get
+ {
+ return Name;
+ }
+ }
+
+ public IType Type
+ {
+ get
+ {
+ return this;
+ }
+ }
+
+ public bool IsFinal
+ {
+ get
+ {
+ return true;
+ }
+ }
+
+ public bool IsByRef
+ {
+ get
+ {
+ return false;
+ }
+ }
+
+ public bool IsClass
+ {
+ get
+ {
+ return false;
+ }
+ }
+
+ public bool IsInterface
+ {
+ get
+ {
+ return false;
+ }
+ }
+
+ public bool IsAbstract
+ {
+ get
+ {
+ return false;
+ }
+ }
+
+ public bool IsEnum
+ {
+ get
+ {
+ return false;
+ }
+ }
+
+ public bool IsValueType
+ {
+ get
+ {
+ return false;
+ }
+ }
+
+ public bool IsArray
+ {
+ get
+ {
+ return true;
+ }
+ }
+
+ public int GetTypeDepth()
+ {
+ return 2;
+ }
+
+ public int GetArrayRank()
+ {
+ return _rank;
+ }
+
+ public IType GetElementType()
+ {
+ return _elementType;
+ }
+
+ public IType BaseType
+ {
+ get
+ {
+ return _array;
+ }
+ }
+
+ public IEntity GetDefaultMember()
+ {
+ return null;
+ }
+
+ public virtual bool IsSubclassOf(IType other)
+ {
+ return other.IsAssignableFrom(_array);
+ }
+
+ public virtual bool IsAssignableFrom(IType other)
+ {
+ if (other == this || other == Null.Default)
+ {
+ return true;
+ }
+
+ if (other.IsArray)
+ {
+ IArrayType otherArray = (IArrayType)other;
+
+ if (otherArray.GetArrayRank() != _rank)
+ {
+ return false;
+ }
+
+ IType otherEntityType = otherArray.GetElementType();
+ if (_elementType.IsValueType || otherEntityType.IsValueType)
+ {
+ return _elementType == otherEntityType;
+ }
+ return _elementType.IsAssignableFrom(otherEntityType);
+ }
+ return false;
+ }
+
+ public IConstructor[] GetConstructors()
+ {
+ return new IConstructor[0];
+ }
+
+ public IType[] GetInterfaces()
+ {
+ return null;
+ }
+
+ public IEntity[] GetMembers()
+ {
+ return _array.GetMembers();
+ }
+
+ public INamespace ParentNamespace
+ {
+ get
+ {
+ return _array.ParentNamespace;
+ }
+ }
+
+ public bool Resolve(List targetList, string name, EntityType flags)
+ {
+ return _array.Resolve(targetList, name, flags);
+ }
+
+ override public string ToString()
+ {
+ return Name;
+ }
+
+ IGenericTypeDefinitionInfo IType.GenericTypeDefinitionInfo
+ {
+ get { return null; }
+ }
+
+ IGenericTypeInfo IType.GenericTypeInfo
+ {
+ get { return null; }
+ }
+ }
+}
Index: src/Boo.Lang.Compiler/TypeSystem/Error.cs
===================================================================
--- src/Boo.Lang.Compiler/TypeSystem/Error.cs (revision 2352)
+++ src/Boo.Lang.Compiler/TypeSystem/Error.cs (working copy)
@@ -185,6 +185,16 @@
{
return Name;
}
+
+ IGenericTypeDefinitionInfo IType.GenericTypeDefinitionInfo
+ {
+ get { return null; }
+ }
+
+ IGenericTypeInfo IType.GenericTypeInfo
+ {
+ get { return null; }
+ }
}
public class Null : AbstractType
Index: src/Boo.Lang.Compiler/TypeSystem/ExternalField.cs
===================================================================
--- src/Boo.Lang.Compiler/TypeSystem/ExternalField.cs (revision 2352)
+++ src/Boo.Lang.Compiler/TypeSystem/ExternalField.cs (working copy)
@@ -30,7 +30,7 @@
{
public class ExternalField : IField
{
- TypeSystemServices _typeSystemServices;
+ protected TypeSystemServices _typeSystemServices;
System.Reflection.FieldInfo _field;
@@ -40,7 +40,7 @@
_field = field;
}
- public IType DeclaringType
+ public virtual IType DeclaringType
{
get
{
@@ -60,7 +60,7 @@
{
get
{
- return _field.DeclaringType.FullName + "." + _field.Name;
+ return DeclaringType.FullName + "." + _field.Name;
}
}
@@ -128,7 +128,7 @@
}
}
- public IType Type
+ public virtual IType Type
{
get
{
Index: src/Boo.Lang.Compiler/TypeSystem/ExternalGenericType.cs
===================================================================
--- src/Boo.Lang.Compiler/TypeSystem/ExternalGenericType.cs (revision 2352)
+++ src/Boo.Lang.Compiler/TypeSystem/ExternalGenericType.cs (working copy)
@@ -1,89 +0,0 @@
-#region license
-// Copyright (c) 2003, 2004, 2005 Rodrigo B. de Oliveira (rbo@acm.org)
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without modification,
-// are permitted provided that the following conditions are met:
-//
-// * Redistributions of source code must retain the above copyright notice,
-// this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above copyright notice,
-// this list of conditions and the following disclaimer in the documentation
-// and/or other materials provided with the distribution.
-// * Neither the name of Rodrigo B. de Oliveira nor the names of its
-// contributors may be used to endorse or promote products derived from this
-// software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#endregion
-
-namespace Boo.Lang.Compiler.TypeSystem
-{
- using System;
-
- public class ExternalGenericType : ExternalType, IGenericType
- {
- IType[] _arguments = null;
- bool _constructed;
-
-#if NET_2_0
- public ExternalGenericType(TypeSystemServices tss, Type type) : base(tss, type)
- {
- _constructed = !type.ContainsGenericParameters;
- }
-
- public IType[] GetGenericArguments()
- {
- if (_arguments == null)
- {
- Type[] actualArguments = ActualType.GetGenericArguments();
- _arguments = new IType[actualArguments.Length];
-
- Converter map = _typeSystemServices.Map;
- _arguments = Array.ConvertAll(actualArguments, map);
- }
-
- return _arguments;
- }
-
- public IGenericTypeDefinition GetGenericTypeDefinition()
- {
- return (IGenericTypeDefinition)_typeSystemServices.Map(ActualType.GetGenericTypeDefinition());
- }
-
- public bool FullyConstructed
- {
- get { return _constructed; }
- }
-
-#else
- public ExternalGenericType(TypeSystemServices tss, Type type) : base(tss, type)
- {
- }
-
- IType[] IGenericType.GetGenericArguments()
- {
- throw new NotImplementedException();
- }
-
- IGenericTypeDefinition IGenericType.GetGenericTypeDefinition()
- {
- throw new NotImplementedException();
- }
-
- bool IGenericType.FullyConstructed
- {
- get { throw new NotImplementedException(); }
- }
-#endif
- }
-}
Index: src/Boo.Lang.Compiler/TypeSystem/ExternalGenericTypeDefinition.cs
===================================================================
--- src/Boo.Lang.Compiler/TypeSystem/ExternalGenericTypeDefinition.cs (revision 2352)
+++ src/Boo.Lang.Compiler/TypeSystem/ExternalGenericTypeDefinition.cs (working copy)
@@ -1,121 +0,0 @@
-#region license
-// Copyright (c) 2003, 2004, 2005 Rodrigo B. de Oliveira (rbo@acm.org)
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without modification,
-// are permitted provided that the following conditions are met:
-//
-// * Redistributions of source code must retain the above copyright notice,
-// this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above copyright notice,
-// this list of conditions and the following disclaimer in the documentation
-// and/or other materials provided with the distribution.
-// * Neither the name of Rodrigo B. de Oliveira nor the names of its
-// contributors may be used to endorse or promote products derived from this
-// software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#endregion
-
-
-namespace Boo.Lang.Compiler.TypeSystem
-{
- using System;
-
-#if NET_2_0
- public class ExternalGenericTypeDefinition : ExternalType, IGenericTypeDefinition
- {
- private IGenericParameter[] _parameters;
-
- public ExternalGenericTypeDefinition(TypeSystemServices tss, Type type) : base(tss, type)
- {
- }
-
- public IGenericParameter[] GetGenericParameters()
- {
- if (null == _parameters) _parameters = CreateParameters();
- return _parameters;
- }
-
- public IType MakeGenericType(IType[] arguments)
- {
- return _typeSystemServices.Map(ActualType.MakeGenericType(ToSystemType(arguments)));
- }
-
- private Type[] ToSystemType(IType[] arguments)
- {
- Type[] externalTypes = new Type[arguments.Length];
- for (int i = 0; i < arguments.Length; ++i)
- {
- ExternalType externalType = arguments[i] as ExternalType;
- if (null == externalType) throw new NotImplementedException("only generics for externally defined types for now");
- externalTypes[i] = externalType.ActualType;
- }
- return externalTypes;
- }
-
- protected override string BuildFullName()
- {
- string name = ActualType.FullName;
- return name.Substring(0, name.IndexOf('`'));
- }
-
- private IGenericParameter[] CreateParameters()
- {
- Type[] arguments = this.ActualType.GetGenericArguments();
- IGenericParameter[] parameters = new IGenericParameter[arguments.Length];
- for (int i=0; i _instances;
+
+ public ExternalGenericTypeDefinitionInfo(TypeSystemServices tss, ExternalType type)
+ {
+ _tss = tss;
+ _type = type;
+ _instances = new Dictionary(new GenericArgumentsComparer());
+ }
+
+ public IGenericParameter[] GenericParameters
+ {
+ get
+ {
+ if (null == _parameters)
+ {
+ _parameters = Array.ConvertAll(
+ _type.ActualType.GetGenericArguments(),
+ delegate(Type t) { return new ExternalGenericParameter(_tss, t); });
+ }
+ return _parameters;
+ }
+ }
+
+ public IType MakeGenericType(IType[] arguments)
+ {
+ if (Array.TrueForAll(arguments, delegate(IType t) { return t is ExternalType; }))
+ {
+ Type[] actualTypes = Array.ConvertAll(
+ arguments,
+ delegate(IType t) { return ((ExternalType)t).ActualType; });
+
+ return _tss.Map(_type.ActualType.MakeGenericType(actualTypes));
+ }
+ else if (_instances.ContainsKey(arguments))
+ {
+ return _instances[arguments];
+ }
+ else
+ {
+ IType instance = CreateMixedType(arguments);
+ _instances.Add(arguments, instance);
+
+ return instance;
+ }
+ }
+
+ private IType CreateMixedType(IType[] arguments)
+ {
+ ExternalCallableType callable = _type as ExternalCallableType;
+ if (null != callable)
+ {
+ return new MixedGenericCallableType(_tss, callable, arguments);
+ }
+ else
+ {
+ return new MixedGenericType(_tss, _type, arguments);
+ }
+ }
+
+ private class GenericArgumentsComparer: IEqualityComparer
+ {
+ public bool Equals(IType[] x, IType[] y)
+ {
+ for (int i = 0; i < x.Length; i++)
+ {
+ if ((x[i] == null && y[i] != null) || (!x[i].Equals(y[i])))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public int GetHashCode(IType[] args)
+ {
+ // Make a simple hash code from the hash codes of the arguments
+ int hash = 0;
+ for (int i = 0; i < args.Length; i++)
+ {
+ hash ^= i ^ args[i].GetHashCode();
+ }
+
+ return hash;
+ }
+ }
+ }
+
+
+ public class ExternalGenericParameter : ExternalType, IGenericParameter
+ {
+ public ExternalGenericParameter(TypeSystemServices tss, Type type) : base(tss, type)
+ {
+ }
+
+ public int GenericParameterPosition
+ {
+ get { return ActualType.GenericParameterPosition; }
+ }
+ }
+}
+
+#endif
Index: src/Boo.Lang.Compiler/TypeSystem/ExternalGenericTypeInfo.cs
===================================================================
--- src/Boo.Lang.Compiler/TypeSystem/ExternalGenericTypeInfo.cs (revision 2352)
+++ src/Boo.Lang.Compiler/TypeSystem/ExternalGenericTypeInfo.cs (working copy)
@@ -1,89 +1,79 @@
-#region license
-// Copyright (c) 2003, 2004, 2005 Rodrigo B. de Oliveira (rbo@acm.org)
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without modification,
-// are permitted provided that the following conditions are met:
-//
-// * Redistributions of source code must retain the above copyright notice,
-// this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above copyright notice,
-// this list of conditions and the following disclaimer in the documentation
-// and/or other materials provided with the distribution.
-// * Neither the name of Rodrigo B. de Oliveira nor the names of its
-// contributors may be used to endorse or promote products derived from this
-// software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#endregion
-
-namespace Boo.Lang.Compiler.TypeSystem
-{
- using System;
-
- public class ExternalGenericType : ExternalType, IGenericType
- {
- IType[] _arguments = null;
- bool _constructed;
-
-#if NET_2_0
- public ExternalGenericType(TypeSystemServices tss, Type type) : base(tss, type)
- {
- _constructed = !type.ContainsGenericParameters;
- }
-
- public IType[] GetGenericArguments()
- {
- if (_arguments == null)
- {
- Type[] actualArguments = ActualType.GetGenericArguments();
- _arguments = new IType[actualArguments.Length];
-
- Converter map = _typeSystemServices.Map;
- _arguments = Array.ConvertAll(actualArguments, map);
- }
-
- return _arguments;
- }
-
- public IGenericTypeDefinition GetGenericTypeDefinition()
- {
- return (IGenericTypeDefinition)_typeSystemServices.Map(ActualType.GetGenericTypeDefinition());
- }
-
- public bool FullyConstructed
- {
- get { return _constructed; }
- }
-
-#else
- public ExternalGenericType(TypeSystemServices tss, Type type) : base(tss, type)
- {
- }
-
- IType[] IGenericType.GetGenericArguments()
- {
- throw new NotImplementedException();
- }
-
- IGenericTypeDefinition IGenericType.GetGenericTypeDefinition()
- {
- throw new NotImplementedException();
- }
-
- bool IGenericType.FullyConstructed
- {
- get { throw new NotImplementedException(); }
- }
-#endif
- }
-}
+#region license
+// Copyright (c) 2003, 2004, 2005 Rodrigo B. de Oliveira (rbo@acm.org)
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+// * Neither the name of Rodrigo B. de Oliveira nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#endregion
+
+#if NET_2_0
+
+namespace Boo.Lang.Compiler.TypeSystem
+{
+ using System;
+
+ public class ExternalGenericTypeInfo : IGenericTypeInfo
+ {
+ TypeSystemServices _tss;
+ ExternalType _type;
+ IType[] _arguments = null;
+ bool _constructed;
+
+ public ExternalGenericTypeInfo(TypeSystemServices tss, ExternalType type)
+ {
+ _tss = tss;
+ _type = type;
+ _constructed = !_type.ActualType.ContainsGenericParameters;
+ }
+
+ public IType[] GenericArguments
+ {
+ get
+ {
+ if (_arguments == null)
+ {
+ _arguments = Array.ConvertAll(
+ _type.ActualType.GetGenericArguments(),
+ _tss.Map);
+ }
+
+ return _arguments;
+ }
+ }
+
+ public IType GenericDefinition
+ {
+ get
+ {
+ return _tss.Map(_type.ActualType.GetGenericTypeDefinition());
+ }
+ }
+
+ public bool FullyConstructed
+ {
+ get { return _constructed; }
+ }
+ }
+}
+
+#endif
Index: src/Boo.Lang.Compiler/TypeSystem/ExternalMethod.cs
===================================================================
--- src/Boo.Lang.Compiler/TypeSystem/ExternalMethod.cs (revision 2352)
+++ src/Boo.Lang.Compiler/TypeSystem/ExternalMethod.cs (working copy)
@@ -1,292 +1,292 @@
-#region license
-// Copyright (c) 2004, Rodrigo B. de Oliveira (rbo@acm.org)
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without modification,
-// are permitted provided that the following conditions are met:
-//
-// * Redistributions of source code must retain the above copyright notice,
-// this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above copyright notice,
-// this list of conditions and the following disclaimer in the documentation
-// and/or other materials provided with the distribution.
-// * Neither the name of Rodrigo B. de Oliveira nor the names of its
-// contributors may be used to endorse or promote products derived from this
-// software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#endregion
-
-namespace Boo.Lang.Compiler.TypeSystem
-{
- using System;
- using System.Reflection;
-
- public class ExternalMethod : IMethod
- {
- protected TypeSystemServices _typeSystemServices;
-
- MethodBase _mi;
-
- IParameter[] _parameters;
-
- ICallableType _type;
-
- int _acceptVarArgs = -1;
-
- int _isDuckTyped = -1;
-
- int _isExtension = -1;
-
- int _isPInvoke = -1;
-
- internal ExternalMethod(TypeSystemServices manager, MethodBase mi)
- {
- _typeSystemServices = manager;
- _mi = mi;
- }
-
- public bool IsExtension
- {
- get
- {
- if (-1 == _isExtension)
- {
- _isExtension = IsStatic && MetadataUtil.IsAttributeDefined(_mi, Types.ExtensionAttribute)
- ? 1
- : 0;
- }
- return 1 == _isExtension;
- }
- }
-
- public bool IsDuckTyped
- {
- get
- {
- if (-1 == _isDuckTyped)
- {
- _isDuckTyped =
- !ReturnType.IsValueType && MetadataUtil.IsAttributeDefined(_mi, Types.DuckTypedAttribute)
- ? 1
- : 0;
- }
- return 1 == _isDuckTyped;
- }
- }
-
- public bool IsPInvoke
- {
- get
- {
- if (-1 == _isPInvoke)
- {
- _isPInvoke = IsStatic && MetadataUtil.IsAttributeDefined(_mi, Types.DllImportAttribute)
- ? 1
- : 0;
- }
- return 1 == _isPInvoke;
- }
- }
-
- public IType DeclaringType
- {
- get
- {
- return _typeSystemServices.Map(_mi.DeclaringType);
- }
- }
-
- public bool IsStatic
- {
- get
- {
- return _mi.IsStatic;
- }
- }
-
- public bool IsPublic
- {
- get
- {
- return _mi.IsPublic;
- }
- }
-
- public bool IsProtected
- {
- get
- {
- return _mi.IsFamily || _mi.IsFamilyOrAssembly;
- }
- }
-
- public bool IsPrivate
- {
- get
- {
- return _mi.IsPrivate;
- }
- }
-
- public bool IsAbstract
- {
- get
- {
- return _mi.IsAbstract;
- }
- }
-
- public bool IsInternal
- {
- get
- {
- return _mi.IsAssembly;
- }
- }
-
- public bool IsVirtual
- {
- get
- {
- return _mi.IsVirtual;
- }
- }
-
- public bool IsSpecialName
- {
- get
- {
- return _mi.IsSpecialName;
- }
- }
-
- public string Name
- {
- get
- {
- return _mi.Name;
- }
- }
-
- public string FullName
- {
- get
- {
- return this.DeclaringType + "." + _mi.Name;
- }
- }
-
- public bool AcceptVarArgs
- {
- get
- {
- if (_acceptVarArgs == -1)
- {
- ParameterInfo[] parameters = _mi.GetParameters();
-
- _acceptVarArgs =
- parameters.Length > 0 && IsParamArray(parameters[parameters.Length-1]) ? 1 : 0;
- }
- return _acceptVarArgs == 1;
- }
- }
-
- private bool IsParamArray(ParameterInfo parameter)
- {
- /* Hack to fix problem with mono-1.1.8.* and older */
- return parameter.ParameterType.IsArray
- && (
- Attribute.IsDefined(parameter, Types.ParamArrayAttribute)
- || parameter.GetCustomAttributes(Types.ParamArrayAttribute, false).Length > 0);
- }
-
-
- public virtual EntityType EntityType
- {
- get
- {
- return EntityType.Method;
- }
- }
-
- public ICallableType CallableType
- {
- get
- {
- if (null == _type)
- {
- _type = _typeSystemServices.GetCallableType(this);
- }
- return _type;
- }
- }
-
- public IType Type
- {
- get
- {
- return CallableType;
- }
- }
-
- public IParameter[] GetParameters()
- {
- if (null == _parameters)
- {
- _parameters = _typeSystemServices.Map(_mi.GetParameters());
- }
- return _parameters;
- }
-
- public virtual IType ReturnType
- {
- get
- {
- MethodInfo mi = _mi as MethodInfo;
- if (null != mi)
- {
- return _typeSystemServices.Map(mi.ReturnType);
- }
- return null;
- }
- }
-
- public MethodBase MethodInfo
- {
- get
- {
- return _mi;
- }
- }
-
- override public bool Equals(object other)
- {
- ExternalMethod rhs = other as ExternalMethod;
- if (null == rhs)
- {
- return false;
- }
- return _mi.MethodHandle.Value == rhs._mi.MethodHandle.Value;
- }
-
- override public int GetHashCode()
- {
- return _mi.MethodHandle.Value.GetHashCode();
- }
-
- override public string ToString()
- {
- return _typeSystemServices.GetSignature(this);
- }
- }
-}
+#region license
+// Copyright (c) 2004, Rodrigo B. de Oliveira (rbo@acm.org)
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+// * Neither the name of Rodrigo B. de Oliveira nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#endregion
+
+namespace Boo.Lang.Compiler.TypeSystem
+{
+ using System;
+ using System.Reflection;
+
+ public class ExternalMethod : IMethod
+ {
+ protected TypeSystemServices _typeSystemServices;
+
+ MethodBase _mi;
+
+ IParameter[] _parameters;
+
+ ICallableType _type;
+
+ int _acceptVarArgs = -1;
+
+ int _isDuckTyped = -1;
+
+ int _isExtension = -1;
+
+ int _isPInvoke = -1;
+
+ internal ExternalMethod(TypeSystemServices manager, MethodBase mi)
+ {
+ _typeSystemServices = manager;
+ _mi = mi;
+ }
+
+ public bool IsExtension
+ {
+ get
+ {
+ if (-1 == _isExtension)
+ {
+ _isExtension = IsStatic && MetadataUtil.IsAttributeDefined(_mi, Types.ExtensionAttribute)
+ ? 1
+ : 0;
+ }
+ return 1 == _isExtension;
+ }
+ }
+
+ public bool IsDuckTyped
+ {
+ get
+ {
+ if (-1 == _isDuckTyped)
+ {
+ _isDuckTyped =
+ !ReturnType.IsValueType && MetadataUtil.IsAttributeDefined(_mi, Types.DuckTypedAttribute)
+ ? 1
+ : 0;
+ }
+ return 1 == _isDuckTyped;
+ }
+ }
+
+ public bool IsPInvoke
+ {
+ get
+ {
+ if (-1 == _isPInvoke)
+ {
+ _isPInvoke = IsStatic && MetadataUtil.IsAttributeDefined(_mi, Types.DllImportAttribute)
+ ? 1
+ : 0;
+ }
+ return 1 == _isPInvoke;
+ }
+ }
+
+ public virtual IType DeclaringType
+ {
+ get
+ {
+ return _typeSystemServices.Map(_mi.DeclaringType);
+ }
+ }
+
+ public bool IsStatic
+ {
+ get
+ {
+ return _mi.IsStatic;
+ }
+ }
+
+ public bool IsPublic
+ {
+ get
+ {
+ return _mi.IsPublic;
+ }
+ }
+
+ public bool IsProtected
+ {
+ get
+ {
+ return _mi.IsFamily || _mi.IsFamilyOrAssembly;
+ }
+ }
+
+ public bool IsPrivate
+ {
+ get
+ {
+ return _mi.IsPrivate;
+ }
+ }
+
+ public bool IsAbstract
+ {
+ get
+ {
+ return _mi.IsAbstract;
+ }
+ }
+
+ public bool IsInternal
+ {
+ get
+ {
+ return _mi.IsAssembly;
+ }
+ }
+
+ public bool IsVirtual
+ {
+ get
+ {
+ return _mi.IsVirtual;
+ }
+ }
+
+ public bool IsSpecialName
+ {
+ get
+ {
+ return _mi.IsSpecialName;
+ }
+ }
+
+ public string Name
+ {
+ get
+ {
+ return _mi.Name;
+ }
+ }
+
+ public string FullName
+ {
+ get
+ {
+ return this.DeclaringType + "." + _mi.Name;
+ }
+ }
+
+ public bool AcceptVarArgs
+ {
+ get
+ {
+ if (_acceptVarArgs == -1)
+ {
+ ParameterInfo[] parameters = _mi.GetParameters();
+
+ _acceptVarArgs =
+ parameters.Length > 0 && IsParamArray(parameters[parameters.Length-1]) ? 1 : 0;
+ }
+ return _acceptVarArgs == 1;
+ }
+ }
+
+ private bool IsParamArray(ParameterInfo parameter)
+ {
+ /* Hack to fix problem with mono-1.1.8.* and older */
+ return parameter.ParameterType.IsArray
+ && (
+ Attribute.IsDefined(parameter, Types.ParamArrayAttribute)
+ || parameter.GetCustomAttributes(Types.ParamArrayAttribute, false).Length > 0);
+ }
+
+
+ public virtual EntityType EntityType
+ {
+ get
+ {
+ return EntityType.Method;
+ }
+ }
+
+ public ICallableType CallableType
+ {
+ get
+ {
+ if (null == _type)
+ {
+ _type = _typeSystemServices.GetCallableType(this);
+ }
+ return _type;
+ }
+ }
+
+ public IType Type
+ {
+ get
+ {
+ return CallableType;
+ }
+ }
+
+ public virtual IParameter[] GetParameters()
+ {
+ if (null == _parameters)
+ {
+ _parameters = _typeSystemServices.Map(_mi.GetParameters());
+ }
+ return _parameters;
+ }
+
+ public virtual IType ReturnType
+ {
+ get
+ {
+ MethodInfo mi = _mi as MethodInfo;
+ if (null != mi)
+ {
+ return _typeSystemServices.Map(mi.ReturnType);
+ }
+ return null;
+ }
+ }
+
+ public MethodBase MethodInfo
+ {
+ get
+ {
+ return _mi;
+ }
+ }
+
+ override public bool Equals(object other)
+ {
+ ExternalMethod rhs = other as ExternalMethod;
+ if (null == rhs)
+ {
+ return false;
+ }
+ return _mi.MethodHandle.Value == rhs._mi.MethodHandle.Value;
+ }
+
+ override public int GetHashCode()
+ {
+ return _mi.MethodHandle.Value.GetHashCode();
+ }
+
+ override public string ToString()
+ {
+ return _typeSystemServices.GetSignature(this);
+ }
+ }
+}
Index: src/Boo.Lang.Compiler/TypeSystem/ExternalParameter.cs
===================================================================
--- src/Boo.Lang.Compiler/TypeSystem/ExternalParameter.cs (revision 2352)
+++ src/Boo.Lang.Compiler/TypeSystem/ExternalParameter.cs (working copy)
@@ -1,84 +1,84 @@
-#region license
-// Copyright (c) 2004, Rodrigo B. de Oliveira (rbo@acm.org)
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without modification,
-// are permitted provided that the following conditions are met:
-//
-// * Redistributions of source code must retain the above copyright notice,
-// this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above copyright notice,
-// this list of conditions and the following disclaimer in the documentation
-// and/or other materials provided with the distribution.
-// * Neither the name of Rodrigo B. de Oliveira nor the names of its
-// contributors may be used to endorse or promote products derived from this
-// software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#endregion
-
-namespace Boo.Lang.Compiler.TypeSystem
-{
- using System.Reflection;
-
- public class ExternalParameter : IParameter
- {
- TypeSystemServices _typeSystemServices;
- ParameterInfo _parameter;
-
- public ExternalParameter(TypeSystemServices service, ParameterInfo parameter)
- {
- _typeSystemServices = service;
- _parameter = parameter;
- }
-
- public string Name
- {
- get
- {
- return _parameter.Name;
- }
- }
-
- public string FullName
- {
- get
- {
- return _parameter.Name;
- }
- }
-
- public EntityType EntityType
- {
- get
- {
- return EntityType.Parameter;
- }
- }
-
- public IType Type
- {
- get
- {
- return _typeSystemServices.Map(_parameter.ParameterType);
- }
- }
-
- public bool IsByRef
- {
- get
- {
- return Type.IsByRef;
- }
- }
- }
-}
+#region license
+// Copyright (c) 2004, Rodrigo B. de Oliveira (rbo@acm.org)
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+// * Neither the name of Rodrigo B. de Oliveira nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#endregion
+
+namespace Boo.Lang.Compiler.TypeSystem
+{
+ using System.Reflection;
+
+ public class ExternalParameter : IParameter
+ {
+ TypeSystemServices _typeSystemServices;
+ protected ParameterInfo _parameter;
+
+ public ExternalParameter(TypeSystemServices service, ParameterInfo parameter)
+ {
+ _typeSystemServices = service;
+ _parameter = parameter;
+ }
+
+ public string Name
+ {
+ get
+ {
+ return _parameter.Name;
+ }
+ }
+
+ public string FullName
+ {
+ get
+ {
+ return _parameter.Name;
+ }
+ }
+
+ public EntityType EntityType
+ {
+ get
+ {
+ return EntityType.Parameter;
+ }
+ }
+
+ public virtual IType Type
+ {
+ get
+ {
+ return _typeSystemServices.Map(_parameter.ParameterType);
+ }
+ }
+
+ public bool IsByRef
+ {
+ get
+ {
+ return Type.IsByRef;
+ }
+ }
+ }
+}
Index: src/Boo.Lang.Compiler/TypeSystem/ExternalProperty.cs
===================================================================
--- src/Boo.Lang.Compiler/TypeSystem/ExternalProperty.cs (revision 2352)
+++ src/Boo.Lang.Compiler/TypeSystem/ExternalProperty.cs (working copy)
@@ -30,7 +30,7 @@
{
public class ExternalProperty : IProperty
{
- TypeSystemServices _typeSystemServices;
+ protected TypeSystemServices _typeSystemServices;
System.Reflection.PropertyInfo _property;
@@ -60,7 +60,7 @@
}
}
- public IType DeclaringType
+ public virtual IType DeclaringType
{
get
{
@@ -154,7 +154,7 @@
{
get
{
- return _property.DeclaringType.FullName + "." + _property.Name;
+ return DeclaringType.FullName + "." + Name;
}
}
@@ -166,7 +166,7 @@
}
}
- public IType Type
+ public virtual IType Type
{
get
{
@@ -190,7 +190,7 @@
}
}
- public IParameter[] GetParameters()
+ public virtual IParameter[] GetParameters()
{
if (null == _parameters)
{
@@ -199,7 +199,7 @@
return _parameters;
}
- public IMethod GetGetMethod()
+ public virtual IMethod GetGetMethod()
{
System.Reflection.MethodInfo getter = _property.GetGetMethod(true);
if (null != getter)
@@ -209,7 +209,7 @@
return null;
}
- public IMethod GetSetMethod()
+ public virtual IMethod GetSetMethod()
{
System.Reflection.MethodInfo setter = _property.GetSetMethod(true);
if (null != setter)
Index: src/Boo.Lang.Compiler/TypeSystem/ExternalType.cs
===================================================================
--- src/Boo.Lang.Compiler/TypeSystem/ExternalType.cs (revision 2352)
+++ src/Boo.Lang.Compiler/TypeSystem/ExternalType.cs (working copy)
@@ -1,408 +1,455 @@
-#region license
-// Copyright (c) 2004, Rodrigo B. de Oliveira (rbo@acm.org)
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without modification,
-// are permitted provided that the following conditions are met:
-//
-// * Redistributions of source code must retain the above copyright notice,
-// this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above copyright notice,
-// this list of conditions and the following disclaimer in the documentation
-// and/or other materials provided with the distribution.
-// * Neither the name of Rodrigo B. de Oliveira nor the names of its
-// contributors may be used to endorse or promote products derived from this
-// software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#endregion
-
-namespace Boo.Lang.Compiler.TypeSystem
-{
- using System;
- using System.Reflection;
-
- public class ExternalType : IType
- {
- protected TypeSystemServices _typeSystemServices;
-
- Type _type;
-
- IConstructor[] _constructors;
-
- IType[] _interfaces;
-
- IEntity[] _members;
-
- int _typeDepth = -1;
-
- string _primitiveName;
-
- string _fullName;
-
- internal ExternalType(TypeSystemServices tss, Type type)
- {
- if (null == type)
- {
- throw new ArgumentException("type");
- }
- _typeSystemServices = tss;
- _type = type;
- }
-
- public string FullName
- {
- get
- {
- if (null == _fullName)
- {
- _fullName = BuildFullName();
- }
- return _fullName;
- }
- }
-
- internal string PrimitiveName
- {
- get
- {
- return _primitiveName;
- }
-
- set
- {
- _primitiveName = value;
- }
- }
-
- public string Name
- {
- get
- {
- return _type.Name;
- }
- }
-
- public EntityType EntityType
- {
- get
- {
- return EntityType.Type;
- }
- }
-
- public IType Type
- {
- get
- {
- return this;
- }
- }
-
- public virtual bool IsFinal
- {
- get
- {
- return _type.IsSealed;
- }
- }
-
- public bool IsByRef
- {
- get
- {
- return _type.IsByRef;
- }
- }
-
- public IType DeclaringType
- {
- get
- {
- System.Type declaringType = _type.DeclaringType;
- return null != declaringType
- ? _typeSystemServices.Map(declaringType)
- : null;
- }
- }
-
- public IType GetElementType()
- {
- return _typeSystemServices.Map(_type.GetElementType());
- }
-
- public bool IsClass
- {
- get
- {
- return _type.IsClass;
- }
- }
-
- public bool IsAbstract
- {
- get
- {
- return _type.IsAbstract;
- }
- }
-
- public bool IsInterface
- {
- get
- {
- return _type.IsInterface;
- }
- }
-
- public bool IsEnum
- {
- get
- {
- return _type.IsEnum;
- }
- }
-
- public bool IsValueType
- {
- get
- {
- return _type.IsValueType;
- }
- }
-
- public bool IsArray
- {
- get
- {
- return false;
- }
- }
-
- public IType BaseType
- {
- get
- {
-
- Type baseType = _type.BaseType;
- return null == baseType
- ? null
- : _typeSystemServices.Map(baseType);
- }
- }
-
- public IEntity GetDefaultMember()
- {
- return _typeSystemServices.Map(_type.GetDefaultMembers());
- }
-
- public Type ActualType
- {
- get
- {
- return _type;
- }
- }
-
- public virtual bool IsSubclassOf(IType other)
- {
- ExternalType external = other as ExternalType;
- if (null == external /*|| _typeSystemServices.VoidType == other*/)
- {
- return false;
- }
-
- return _type.IsSubclassOf(external._type) ||
- (external.IsInterface && external._type.IsAssignableFrom(_type))
- ;
- }
-
- public virtual bool IsAssignableFrom(IType other)
- {
- ExternalType external = other as ExternalType;
- if (null == external)
- {
- if (EntityType.Null == other.EntityType)
- {
- return !IsValueType;
- }
- return other.IsSubclassOf(this);
- }
- if (other == _typeSystemServices.VoidType)
- {
- return false;
- }
- return _type.IsAssignableFrom(external._type);
- }
-
- public IConstructor[] GetConstructors()
- {
- if (null == _constructors)
- {
- BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
- ConstructorInfo[] ctors = _type.GetConstructors(flags);
- _constructors = new IConstructor[ctors.Length];
- for (int i=0; i<_constructors.Length; ++i)
- {
- _constructors[i] = new ExternalConstructor(_typeSystemServices, ctors[i]);
- }
- }
- return _constructors;
- }
-
- public IType[] GetInterfaces()
- {
- if (null == _interfaces)
- {
- Type[] interfaces = _type.GetInterfaces();
- _interfaces = new IType[interfaces.Length];
- for (int i=0; i<_interfaces.Length; ++i)
- {
- _interfaces[i] = _typeSystemServices.Map(interfaces[i]);
- }
- }
- return _interfaces;
- }
-
- public IEntity[] GetMembers()
- {
- if (null == _members)
- {
- BindingFlags flags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static;// | BindingFlags.FlattenHierarchy;
- MemberInfo[] members = _type.GetMembers(flags);
- Type[] nested = _type.GetNestedTypes();
- _members = new IEntity[members.Length+nested.Length];
- int i = 0;
- for (i=0; i 0)
- {
- int current = 0;
- foreach (Type i in interfaces)
- {
- int depth = GetInterfaceDepth(i);
- if (depth > current)
- {
- current = depth;
- }
- }
- return 1+current;
- }
- return 1;
- }
-
- protected virtual string BuildFullName()
- {
- if (_type.IsByRef) return "ref " + this.GetElementType().ToString();
- if (_type.DeclaringType != null) return this.DeclaringType.ToString() + "." + _type.Name;
- return _type.FullName;
- }
- }
-}
+#region license
+// Copyright (c) 2004, Rodrigo B. de Oliveira (rbo@acm.org)
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+// * Neither the name of Rodrigo B. de Oliveira nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#endregion
+
+namespace Boo.Lang.Compiler.TypeSystem
+{
+ using System;
+ using System.Reflection;
+
+ public class ExternalType : IType
+ {
+ protected TypeSystemServices _typeSystemServices;
+
+ Type _type;
+
+ IConstructor[] _constructors;
+
+ IType[] _interfaces;
+
+ IEntity[] _members;
+
+ int _typeDepth = -1;
+
+ string _primitiveName;
+
+ string _fullName;
+
+ internal ExternalType(TypeSystemServices tss, Type type)
+ {
+ if (null == type)
+ {
+ throw new ArgumentException("type");
+ }
+ _typeSystemServices = tss;
+ _type = type;
+ }
+
+ public virtual string FullName
+ {
+ get
+ {
+ if (null == _fullName)
+ {
+ _fullName = BuildFullName();
+ }
+ return _fullName;
+ }
+ }
+
+ internal string PrimitiveName
+ {
+ get
+ {
+ return _primitiveName;
+ }
+
+ set
+ {
+ _primitiveName = value;
+ }
+ }
+
+ public virtual string Name
+ {
+ get
+ {
+ return _type.Name;
+ }
+ }
+
+ public EntityType EntityType
+ {
+ get
+ {
+ return EntityType.Type;
+ }
+ }
+
+ public IType Type
+ {
+ get
+ {
+ return this;
+ }
+ }
+
+ public virtual bool IsFinal
+ {
+ get
+ {
+ return _type.IsSealed;
+ }
+ }
+
+ public bool IsByRef
+ {
+ get
+ {
+ return _type.IsByRef;
+ }
+ }
+
+ public IType DeclaringType
+ {
+ get
+ {
+ System.Type declaringType = _type.DeclaringType;
+ return null != declaringType
+ ? _typeSystemServices.Map(declaringType)
+ : null;
+ }
+ }
+
+ public virtual IType GetElementType()
+ {
+ return _typeSystemServices.Map(_type.GetElementType());
+ }
+
+ public bool IsClass
+ {
+ get
+ {
+ return _type.IsClass;
+ }
+ }
+
+ public bool IsAbstract
+ {
+ get
+ {
+ return _type.IsAbstract;
+ }
+ }
+
+ public bool IsInterface
+ {
+ get
+ {
+ return _type.IsInterface;
+ }
+ }
+
+ public bool IsEnum
+ {
+ get
+ {
+ return _type.IsEnum;
+ }
+ }
+
+ public bool IsValueType
+ {
+ get
+ {
+ return _type.IsValueType;
+ }
+ }
+
+ public bool IsArray
+ {
+ get
+ {
+ return false;
+ }
+ }
+
+ public virtual IType BaseType
+ {
+ get
+ {
+
+ Type baseType = _type.BaseType;
+ return null == baseType
+ ? null
+ : _typeSystemServices.Map(baseType);
+ }
+ }
+
+ public virtual IEntity GetDefaultMember()
+ {
+ return _typeSystemServices.Map(_type.GetDefaultMembers());
+ }
+
+ public Type ActualType
+ {
+ get
+ {
+ return _type;
+ }
+ }
+
+ public virtual bool IsSubclassOf(IType other)
+ {
+ ExternalType external = other as ExternalType;
+ if (null == external /*|| _typeSystemServices.VoidType == other*/)
+ {
+ return false;
+ }
+
+ return _type.IsSubclassOf(external._type) ||
+ (external.IsInterface && external._type.IsAssignableFrom(_type))
+ ;
+ }
+
+ public virtual bool IsAssignableFrom(IType other)
+ {
+ ExternalType external = other as ExternalType;
+ if (null == external)
+ {
+ if (EntityType.Null == other.EntityType)
+ {
+ return !IsValueType;
+ }
+ return other.IsSubclassOf(this);
+ }
+ if (other == _typeSystemServices.VoidType)
+ {
+ return false;
+ }
+ return _type.IsAssignableFrom(external._type);
+ }
+
+ public virtual IConstructor[] GetConstructors()
+ {
+ if (null == _constructors)
+ {
+ BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
+ ConstructorInfo[] ctors = _type.GetConstructors(flags);
+ _constructors = new IConstructor[ctors.Length];
+ for (int i=0; i<_constructors.Length; ++i)
+ {
+ _constructors[i] = new ExternalConstructor(_typeSystemServices, ctors[i]);
+ }
+ }
+ return _constructors;
+ }
+
+ public virtual IType[] GetInterfaces()
+ {
+ if (null == _interfaces)
+ {
+ Type[] interfaces = _type.GetInterfaces();
+ _interfaces = new IType[interfaces.Length];
+ for (int i=0; i<_interfaces.Length; ++i)
+ {
+ _interfaces[i] = _typeSystemServices.Map(interfaces[i]);
+ }
+ }
+ return _interfaces;
+ }
+
+ public virtual IEntity[] GetMembers()
+ {
+ if (null == _members)
+ {
+ BindingFlags flags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static;// | BindingFlags.FlattenHierarchy;
+ MemberInfo[] members = _type.GetMembers(flags);
+ Type[] nested = _type.GetNestedTypes();
+ _members = new IEntity[members.Length+nested.Length];
+ int i = 0;
+ for (i=0; i 0)
+ {
+ int current = 0;
+ foreach (Type i in interfaces)
+ {
+ int depth = GetInterfaceDepth(i);
+ if (depth > current)
+ {
+ current = depth;
+ }
+ }
+ return 1+current;
+ }
+ return 1;
+ }
+
+ protected virtual string BuildFullName()
+ {
+ if (_type.IsByRef) return "ref " + this.GetElementType().ToString();
+ if (_type.DeclaringType != null) return this.DeclaringType.ToString() + "." + _type.Name;
+ return _type.FullName;
+ }
+
+#if NET_2_0
+ ExternalGenericTypeDefinitionInfo _genericTypeDefinitionInfo = null;
+ public virtual IGenericTypeDefinitionInfo GenericTypeDefinitionInfo
+ {
+ get
+ {
+ if (ActualType.IsGenericTypeDefinition)
+ {
+ if (_genericTypeDefinitionInfo == null)
+ {
+ _genericTypeDefinitionInfo = new ExternalGenericTypeDefinitionInfo(_typeSystemServices, this);
+ }
+ return _genericTypeDefinitionInfo;
+ }
+ return null;
+ }
+ }
+
+ ExternalGenericTypeInfo _genericTypeInfo = null;
+ public virtual IGenericTypeInfo GenericTypeInfo
+ {
+ get
+ {
+ if (ActualType.IsGenericType)
+ {
+ if (_genericTypeInfo == null)
+ {
+ _genericTypeInfo = new ExternalGenericTypeInfo(_typeSystemServices, this);
+ }
+ return _genericTypeInfo;
+ }
+ return null;
+ }
+ }
+#else
+ IGenericTypeDefinitionInfo IType.GenericTypeDefinitionInfo
+ {
+ get { return null; }
+ }
+
+ IGenericTypeInfo IType.GenericTypeInfo
+ {
+ get { return null; }
+ }
+#endif
+
+ }
+}
Index: src/Boo.Lang.Compiler/TypeSystem/IEntity.cs
===================================================================
--- src/Boo.Lang.Compiler/TypeSystem/IEntity.cs (revision 2352)
+++ src/Boo.Lang.Compiler/TypeSystem/IEntity.cs (working copy)
@@ -1,334 +1,339 @@
-#region license
-// Copyright (c) 2004, Rodrigo B. de Oliveira (rbo@acm.org)
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without modification,
-// are permitted provided that the following conditions are met:
-//
-// * Redistributions of source code must retain the above copyright notice,
-// this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above copyright notice,
-// this list of conditions and the following disclaimer in the documentation
-// and/or other materials provided with the distribution.
-// * Neither the name of Rodrigo B. de Oliveira nor the names of its
-// contributors may be used to endorse or promote products derived from this
-// software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#endregion
-
-namespace Boo.Lang.Compiler.TypeSystem
-{
- public interface IEntity
- {
- string Name
- {
- get;
- }
-
- string FullName
- {
- get;
- }
-
- EntityType EntityType
- {
- get;
- }
- }
-
- public interface IInternalEntity : IEntity
- {
- Boo.Lang.Compiler.Ast.Node Node
- {
- get;
- }
- }
-
- public interface ITypedEntity : IEntity
- {
- IType Type
- {
- get;
- }
- }
-
- public interface IMember : ITypedEntity
- {
- bool IsDuckTyped
- {
- get;
- }
-
- IType DeclaringType
- {
- get;
- }
-
- bool IsStatic
- {
- get;
- }
-
- bool IsPublic
- {
- get;
- }
- }
-
- public interface IExtensionEnabled : IEntityWithParameters
- {
- bool IsExtension { get; }
- }
-
- public interface IEvent : IMember
- {
- IMethod GetAddMethod();
- IMethod GetRemoveMethod();
- IMethod GetRaiseMethod();
-
- bool IsAbstract
- {
- get;
- }
-
- bool IsVirtual
- {
- get;
- }
- }
-
- public interface IField : IAccessibleMember
- {
- bool IsInitOnly
- {
- get;
- }
-
- bool IsLiteral
- {
- get;
- }
-
- object StaticValue
- {
- get;
- }
- }
-
- public interface IProperty : IAccessibleMember, IEntityWithParameters, IExtensionEnabled
- {
- IMethod GetGetMethod();
-
- IMethod GetSetMethod();
- }
-
- public interface IType : ITypedEntity, INamespace
- {
- bool IsClass
- {
- get;
- }
-
- bool IsAbstract
- {
- get;
- }
-
- bool IsInterface
- {
- get;
- }
-
- bool IsEnum
- {
- get;
- }
-
- bool IsByRef
- {
- get;
- }
-
- bool IsValueType
- {
- get;
- }
-
- bool IsFinal
- {
- get;
- }
-
- bool IsArray
- {
- get;
- }
-
- int GetTypeDepth();
-
- IType GetElementType();
-
- IType BaseType
- {
- get;
- }
-
- IEntity GetDefaultMember();
-
- IConstructor[] GetConstructors();
-
- IType[] GetInterfaces();
-
- bool IsSubclassOf(IType other);
-
- bool IsAssignableFrom(IType other);
- }
-
- public interface IGenericParameter : IType
- {
- IGenericTypeDefinition GetDeclaringType();
- bool Constructed { get; }
- }
-
- public interface IGenericTypeDefinition : IType
- {
- IGenericParameter[] GetGenericParameters();
- IType MakeGenericType(IType[] arguments);
- }
-
- public interface IGenericType : IType
- {
- IType[] GetGenericArguments();
- IGenericTypeDefinition GetGenericTypeDefinition();
- bool FullyConstructed { get; }
- }
-
- public interface ICallableType : IType
- {
- CallableSignature GetSignature();
- }
-
- public interface IArrayType : IType
- {
- int GetArrayRank();
- }
-
- public interface ILocalEntity : ITypedEntity
- {
- bool IsPrivateScope
- {
- get;
- }
-
- ///
- /// Is this variable shared among closures?
- ///
- bool IsShared
- {
- get;
- set;
- }
-
- ///
- /// Is this variable ever used in the body of the method?
- ///
- bool IsUsed
- {
- get;
- set;
- }
- }
-
- public interface IParameter : ITypedEntity
- {
- ///
- /// Is the parameter out or ref?
- ///
- bool IsByRef
- {
- get;
- }
- }
-
- public interface IAccessibleMember : IMember
- {
- bool IsProtected
- {
- get;
- }
-
- bool IsInternal
- {
- get;
- }
-
- bool IsPrivate
- {
- get;
- }
- }
-
- public interface IEntityWithParameters : IEntity
- {
- IParameter[] GetParameters();
-
- bool AcceptVarArgs
- {
- get;
- }
- }
-
- public interface IMethodBase : IAccessibleMember, IEntityWithParameters
- {
- ICallableType CallableType
- {
- get;
- }
- }
-
- public interface IMethod : IMethodBase, IExtensionEnabled
- {
- IType ReturnType
- {
- get;
- }
-
- bool IsAbstract
- {
- get;
- }
-
- bool IsVirtual
- {
- get;
- }
-
- bool IsSpecialName
- {
- get;
- }
-
- bool IsPInvoke
- {
- get;
- }
- }
-
- public interface IConstructor : IMethodBase
- {
- }
-
- public interface IDestructor : IMethodBase
- {
- }
-}
+#region license
+// Copyright (c) 2004, Rodrigo B. de Oliveira (rbo@acm.org)
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+// * Neither the name of Rodrigo B. de Oliveira nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#endregion
+
+namespace Boo.Lang.Compiler.TypeSystem
+{
+ public interface IEntity
+ {
+ string Name
+ {
+ get;
+ }
+
+ string FullName
+ {
+ get;
+ }
+
+ EntityType EntityType
+ {
+ get;
+ }
+ }
+
+ public interface IInternalEntity : IEntity
+ {
+ Boo.Lang.Compiler.Ast.Node Node
+ {
+ get;
+ }
+ }
+
+ public interface ITypedEntity : IEntity
+ {
+ IType Type
+ {
+ get;
+ }
+ }
+
+ public interface IMember : ITypedEntity
+ {
+ bool IsDuckTyped
+ {
+ get;
+ }
+
+ IType DeclaringType
+ {
+ get;
+ }
+
+ bool IsStatic
+ {
+ get;
+ }
+
+ bool IsPublic
+ {
+ get;
+ }
+ }
+
+ public interface IExtensionEnabled : IEntityWithParameters
+ {
+ bool IsExtension { get; }
+ }
+
+ public interface IEvent : IMember
+ {
+ IMethod GetAddMethod();
+ IMethod GetRemoveMethod();
+ IMethod GetRaiseMethod();
+
+ bool IsAbstract
+ {
+ get;
+ }
+
+ bool IsVirtual
+ {
+ get;
+ }
+ }
+
+ public interface IField : IAccessibleMember
+ {
+ bool IsInitOnly
+ {
+ get;
+ }
+
+ bool IsLiteral
+ {
+ get;
+ }
+
+ object StaticValue
+ {
+ get;
+ }
+ }
+
+ public interface IProperty : IAccessibleMember, IEntityWithParameters, IExtensionEnabled
+ {
+ IMethod GetGetMethod();
+
+ IMethod GetSetMethod();
+ }
+
+ public interface IType : ITypedEntity, INamespace
+ {
+ bool IsClass
+ {
+ get;
+ }
+
+ bool IsAbstract
+ {
+ get;
+ }
+
+ bool IsInterface
+ {
+ get;
+ }
+
+ bool IsEnum
+ {
+ get;
+ }
+
+ bool IsByRef
+ {
+ get;
+ }
+
+ bool IsValueType
+ {
+ get;
+ }
+
+ bool IsFinal
+ {
+ get;
+ }
+
+ bool IsArray
+ {
+ get;
+ }
+
+ int GetTypeDepth();
+
+ IType GetElementType();
+
+ IType BaseType
+ {
+ get;
+ }
+
+ IEntity GetDefaultMember();
+
+ IConstructor[] GetConstructors();
+
+ IType[] GetInterfaces();
+
+ bool IsSubclassOf(IType other);
+
+ bool IsAssignableFrom(IType other);
+
+ IGenericTypeDefinitionInfo GenericTypeDefinitionInfo { get; }
+
+ IGenericTypeInfo GenericTypeInfo { get; }
+ }
+
+ public interface IGenericTypeDefinitionInfo
+ {
+ IGenericParameter[] GenericParameters { get; }
+ IType MakeGenericType(IType[] arguments);
+ }
+
+ public interface IGenericTypeInfo
+ {
+ IType[] GenericArguments { get; }
+ IType GenericDefinition { get; }
+ bool FullyConstructed { get; }
+ }
+
+ public interface IGenericParameter: IType
+ {
+ IType DeclaringType { get; }
+ int GenericParameterPosition { get; }
+ // TODO: Constraints { get; }
+ }
+
+ public interface ICallableType : IType
+ {
+ CallableSignature GetSignature();
+ }
+
+ public interface IArrayType : IType
+ {
+ int GetArrayRank();
+ }
+
+ public interface ILocalEntity : ITypedEntity
+ {
+ bool IsPrivateScope
+ {
+ get;
+ }
+
+ ///
+ /// Is this variable shared among closures?
+ ///
+ bool IsShared
+ {
+ get;
+ set;
+ }
+
+ ///
+ /// Is this variable ever used in the body of the method?
+ ///
+ bool IsUsed
+ {
+ get;
+ set;
+ }
+ }
+
+ public interface IParameter : ITypedEntity
+ {
+ ///
+ /// Is the parameter out or ref?
+ ///
+ bool IsByRef
+ {
+ get;
+ }
+ }
+
+ public interface IAccessibleMember : IMember
+ {
+ bool IsProtected
+ {
+ get;
+ }
+
+ bool IsInternal
+ {
+ get;
+ }
+
+ bool IsPrivate
+ {
+ get;
+ }
+ }
+
+ public interface IEntityWithParameters : IEntity
+ {
+ IParameter[] GetParameters();
+
+ bool AcceptVarArgs
+ {
+ get;
+ }
+ }
+
+ public interface IMethodBase : IAccessibleMember, IEntityWithParameters
+ {
+ ICallableType CallableType
+ {
+ get;
+ }
+ }
+
+ public interface IMethod : IMethodBase, IExtensionEnabled
+ {
+ IType ReturnType
+ {
+ get;
+ }
+
+ bool IsAbstract
+ {
+ get;
+ }
+
+ bool IsVirtual
+ {
+ get;
+ }
+
+ bool IsSpecialName
+ {
+ get;
+ }
+
+ bool IsPInvoke
+ {
+ get;
+ }
+ }
+
+ public interface IConstructor : IMethodBase
+ {
+ }
+
+ public interface IDestructor : IMethodBase
+ {
+ }
+}
Index: src/Boo.Lang.Compiler/TypeSystem/InternalField.cs
===================================================================
--- src/Boo.Lang.Compiler/TypeSystem/InternalField.cs (revision 2352)
+++ src/Boo.Lang.Compiler/TypeSystem/InternalField.cs (working copy)
@@ -1,181 +1,181 @@
-#region license
-// Copyright (c) 2004, Rodrigo B. de Oliveira (rbo@acm.org)
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without modification,
-// are permitted provided that the following conditions are met:
-//
-// * Redistributions of source code must retain the above copyright notice,
-// this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above copyright notice,
-// this list of conditions and the following disclaimer in the documentation
-// and/or other materials provided with the distribution.
-// * Neither the name of Rodrigo B. de Oliveira nor the names of its
-// contributors may be used to endorse or promote products derived from this
-// software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#endregion
-
-namespace Boo.Lang.Compiler.TypeSystem
+#region license
+// Copyright (c) 2004, Rodrigo B. de Oliveira (rbo@acm.org)
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+// * Neither the name of Rodrigo B. de Oliveira nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#endregion
+
+namespace Boo.Lang.Compiler.TypeSystem
{
using Boo.Lang.Compiler.Ast;
- public class InternalField : IInternalEntity, IField
- {
- Field _field;
- object _staticValue;
-
- public InternalField(Field field)
- {
- _field = field;
- }
-
- public string Name
- {
- get
- {
- return _field.Name;
- }
- }
-
- public string FullName
- {
- get
- {
- return _field.DeclaringType.FullName + "." + _field.Name;
- }
- }
-
- public bool IsStatic
- {
- get
- {
- return _field.IsStatic;
- }
- }
-
- public bool IsPublic
- {
- get
- {
- return _field.IsPublic;
- }
- }
-
- public bool IsProtected
- {
- get
- {
- return _field.IsProtected;
- }
- }
-
+ public class InternalField : IInternalEntity, IField
+ {
+ Field _field;
+ object _staticValue;
+
+ public InternalField(Field field)
+ {
+ _field = field;
+ }
+
+ public string Name
+ {
+ get
+ {
+ return _field.Name;
+ }
+ }
+
+ public string FullName
+ {
+ get
+ {
+ return _field.DeclaringType.FullName + "." + _field.Name;
+ }
+ }
+
+ public bool IsStatic
+ {
+ get
+ {
+ return _field.IsStatic;
+ }
+ }
+
+ public bool IsPublic
+ {
+ get
+ {
+ return _field.IsPublic;
+ }
+ }
+
+ public bool IsProtected
+ {
+ get
+ {
+ return _field.IsProtected;
+ }
+ }
+
public bool IsPrivate
{
get
{
return _field.IsPrivate;
}
- }
-
+ }
+
public bool IsInternal
{
get
{
return _field.IsInternal;
}
- }
-
- public EntityType EntityType
- {
- get
- {
- return EntityType.Field;
- }
- }
-
- public IType Type
- {
- get
- {
- return null != _field.Type
- ? TypeSystemServices.GetType(_field.Type)
- : Unknown.Default;
- }
- }
-
- public IType DeclaringType
- {
- get
- {
- return (IType)TypeSystemServices.GetEntity(_field.ParentNode);
- }
- }
-
- public bool IsLiteral
- {
- get
- {
- //return IsStatic && IsInitOnly && TypeSystemServices.IsPrimitiveTypeOrString(Type);
- return null != _staticValue;
- }
- }
-
- public bool IsInitOnly
- {
- get
- {
- return _field.IsFinal;
- }
- }
-
- public object StaticValue
- {
- get
- {
- return _staticValue;
- }
-
- set
- {
- _staticValue = value;
- }
- }
-
- public Node Node
- {
- get
- {
- return _field;
- }
- }
-
- public Field Field
- {
- get
- {
- return _field;
- }
- }
-
- override public string ToString()
- {
- return FullName;
- }
-
+ }
+
+ public EntityType EntityType
+ {
+ get
+ {
+ return EntityType.Field;
+ }
+ }
+
+ public IType Type
+ {
+ get
+ {
+ return null != _field.Type
+ ? TypeSystemServices.GetType(_field.Type)
+ : Unknown.Default;
+ }
+ }
+
+ public IType DeclaringType
+ {
+ get
+ {
+ return (IType)TypeSystemServices.GetEntity(_field.ParentNode);
+ }
+ }
+
+ public bool IsLiteral
+ {
+ get
+ {
+ //return IsStatic && IsInitOnly && TypeSystemServices.IsPrimitiveTypeOrString(Type);
+ return null != _staticValue;
+ }
+ }
+
+ public bool IsInitOnly
+ {
+ get
+ {
+ return _field.IsFinal;
+ }
+ }
+
+ public object StaticValue
+ {
+ get
+ {
+ return _staticValue;
+ }
+
+ set
+ {
+ _staticValue = value;
+ }
+ }
+
+ public Node Node
+ {
+ get
+ {
+ return _field;
+ }
+ }
+
+ public Field Field
+ {
+ get
+ {
+ return _field;
+ }
+ }
+
+ override public string ToString()
+ {
+ return FullName;
+ }
+
public bool IsDuckTyped
{
get { return false; }
- }
- }
-}
+ }
+ }
+}
Index: src/Boo.Lang.Compiler/TypeSystem/MixedGenericType.cs
===================================================================
--- src/Boo.Lang.Compiler/TypeSystem/MixedGenericType.cs (revision 0)
+++ src/Boo.Lang.Compiler/TypeSystem/MixedGenericType.cs (revision 0)
@@ -0,0 +1,565 @@
+#region license
+// Copyright (c) 2003, 2004, 2005 Rodrigo B. de Oliveira (rbo@acm.org)
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+// * Neither the name of Rodrigo B. de Oliveira nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#endregion
+
+#if NET_2_0
+
+namespace Boo.Lang.Compiler.TypeSystem
+{
+ using System;
+ using System.Text;
+ using System.Reflection;
+ using System.Collections.Generic;
+
+ ///
+ /// A generic type constructed from an external definition but involving internal parameters.
+ ///
+ public class MixedGenericType : ExternalType, IGenericTypeInfo
+ {
+ #region Data Members
+
+ ExternalType _definition;
+ IType[] _arguments = null;
+ bool _constructed;
+ string _name = null;
+ string _fullName = null;
+ Dictionary _mappedMembers = new Dictionary();
+
+ #endregion
+
+ #region Constructor
+
+ public MixedGenericType(TypeSystemServices tss, ExternalType definition, IType[] arguments) : base(tss, definition.ActualType)
+ {
+ _definition = definition;
+ _arguments = arguments;
+ _constructed = IsConstructed();
+ }
+
+ #endregion
+
+ #region IGenericTypeInfo members
+
+ public IType[] GenericArguments
+ {
+ get { return _arguments; }
+ }
+
+ public IType GenericDefinition
+ {
+ get { return _definition; }
+ }
+
+ public bool FullyConstructed
+ {
+ get { return _constructed; }
+ }
+
+ #endregion
+
+ #region Properties
+
+ public override IGenericTypeInfo GenericTypeInfo
+ {
+ get { return this; }
+ }
+
+ public override IType BaseType
+ {
+ get { return MapType(_definition.BaseType); }
+ }
+
+ public override string Name
+ {
+ get
+ {
+ if (_name == null)
+ {
+ _name = BuildName(false);
+ }
+ return _name;
+ }
+ }
+
+ public override string FullName
+ {
+ get
+ {
+ if (_fullName == null)
+ {
+ _fullName = BuildName(true);
+ }
+ return _fullName;
+ }
+ }
+
+ #endregion
+
+ #region Private Methods
+
+ private bool IsConstructed()
+ {
+ foreach (IType arg in _arguments)
+ {
+ if (arg is IGenericParameter) return false;
+ }
+
+ return true;
+ }
+
+ private string BuildName(bool full)
+ {
+ Converter argumentName = delegate(IType type)
+ {
+ return full ? "[" + type.FullName + "]" : type.Name;
+ };
+
+ string[] typeNames = Array.ConvertAll(_arguments, argumentName);
+
+ return string.Format(
+ "{0}[{1}]",
+ full ? _definition.FullName : _definition.Name,
+ string.Join(", ", typeNames));
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ public override string ToString()
+ {
+ return FullName;
+ }
+
+ public override IType GetElementType()
+ {
+ return MapType(_definition.GetElementType());
+ }
+
+ public override IEntity GetDefaultMember()
+ {
+ return MapMember(_definition.GetDefaultMember());
+ }
+
+ public override IConstructor[] GetConstructors()
+ {
+ return Array.ConvertAll(
+ _definition.GetConstructors(),
+ delegate(IConstructor c) { return (IConstructor)MapMember(c); });
+ }
+
+ public override IType[] GetInterfaces()
+ {
+ return Array.ConvertAll(
+ _definition.GetInterfaces(),
+ MapType);
+ }
+
+ public override IEntity[] GetMembers()
+ {
+ return Array.ConvertAll(
+ _definition.GetMembers(),
+ MapMember);
+ }
+
+ public override bool IsSubclassOf(IType other)
+ {
+ if (BaseType != null && (BaseType == other || BaseType.IsSubclassOf(other)))
+ {
+ return true;
+ }
+
+ if (other.IsInterface && Array.Exists(
+ GetInterfaces(),
+ delegate(IType i) { return other.IsAssignableFrom(i); }))
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ public override bool IsAssignableFrom(IType other)
+ {
+ if (other == null)
+ {
+ return false;
+ }
+
+ if (other == this || other.IsSubclassOf(this))
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ #endregion
+
+ #region Mapping methods
+
+ ///
+ /// Maps a type involving generic parameters to the corresponding type after substituting concrete
+ /// arguments for generic parameters.
+ ///
+ ///
+ /// If the source type is a generic parameter of this type's definition, it is mapped to the
+ /// corresponding argument.
+ /// If the source type is an open generic type using parameters from the type's definition, it
+ /// is mapped to a closed constructed type based on this type's arguments.
+ /// If the source type is an array of a generic parameter of this type's definition, it is mapped
+ /// to the array type of the corresponding argument, of the same rank.
+ ///
+ protected IType MapType(IType sourceType)
+ {
+ if (sourceType == null)
+ {
+ return null;
+ }
+
+ // Map generic parameter to corresponding argument
+ IGenericParameter gp = sourceType as IGenericParameter;
+ if (null != gp && gp.DeclaringType == _definition)
+ {
+ return GenericArguments[gp.GenericParameterPosition];
+ }
+
+ // Map open constructed type using generic parameters to closed constructed type
+ // using corresponding arguments
+ if (null != sourceType.GenericTypeInfo && !sourceType.GenericTypeInfo.FullyConstructed)
+ {
+ IType[] mappedArguments = Array.ConvertAll(
+ sourceType.GenericTypeInfo.GenericArguments,
+ MapType);
+
+ return sourceType.GenericTypeInfo.
+ GenericDefinition.GenericTypeDefinitionInfo.
+ MakeGenericType(mappedArguments);
+ }
+
+ // Map array of generic parameter to array of corresponding argument
+ IArrayType array = (sourceType as IArrayType);
+ if (array != null)
+ {
+ return _typeSystemServices.GetArrayType(MapType(array.GetElementType()), array.GetArrayRank());
+ }
+
+ // TODO: Handle ref/out types of generic parameters
+
+ // If source type doesn't require mapping, return it as is
+ return sourceType;
+ }
+
+ ///
+ /// Maps a member from the type's definition to its constructed version.
+ ///
+ protected IEntity MapMember(IEntity source)
+ {
+ if (source == null) return null;
+
+ if (_mappedMembers.ContainsKey(source))
+ {
+ return _mappedMembers[source];
+ }
+
+ IEntity mapped = null;
+
+ switch (source.EntityType)
+ {
+ case EntityType.Method:
+ mapped = new MappedMethod(_typeSystemServices, ((ExternalMethod)source).MethodInfo, this);
+ break;
+
+ case EntityType.Constructor:
+ mapped = new MappedConstructor(_typeSystemServices, ((ExternalConstructor)source).ConstructorInfo, this);
+ break;
+
+ case EntityType.Field:
+ mapped = new MappedField(_typeSystemServices, ((ExternalField)source).FieldInfo, this);
+ break;
+
+ case EntityType.Property:
+ mapped = new MappedProperty(_typeSystemServices, ((ExternalProperty)source).PropertyInfo, this);
+ break;
+
+ case EntityType.Type:
+ mapped = MapType((IType)source);
+ break;
+
+ default:
+ throw new ArgumentException(
+ string.Format("Invalid entity type for mapping: {0}.", source.EntityType));
+ }
+
+ _mappedMembers[source] = mapped;
+ return mapped;
+ }
+
+ #endregion
+
+ #region class MappedMethod
+
+ ///
+ /// A method in a mixed generic type.
+ ///
+ public class MappedMethod : ExternalMethod
+ {
+ private MixedGenericType _parentType;
+
+ public MappedMethod(TypeSystemServices tss, MethodBase method, MixedGenericType parentType) : base(tss, method)
+ {
+ _parentType = parentType;
+ }
+
+ public override IType DeclaringType
+ {
+ get { return _parentType; }
+ }
+
+ public override IType ReturnType
+ {
+ get
+ {
+ return _parentType.MapType(base.ReturnType);
+ }
+ }
+
+ public override IParameter[] GetParameters()
+ {
+ return Array.ConvertAll(
+ base.GetParameters(),
+ delegate(IParameter p)
+ {
+ return new MappedParameter(_typeSystemServices, (ExternalParameter)p, _parentType);
+ });
+ }
+ }
+
+ #endregion
+
+ #region class MappedConstructor
+
+ ///
+ /// A constructor in a mixed generic type.
+ ///
+ public class MappedConstructor : MappedMethod, IConstructor
+ {
+ public MappedConstructor(TypeSystemServices tss, ConstructorInfo ci, MixedGenericType parentType) : base(tss, ci, parentType)
+ {
+ }
+
+ public override EntityType EntityType
+ {
+ get { return EntityType.Constructor; }
+ }
+
+ public override IType ReturnType
+ {
+ get { return _typeSystemServices.VoidType; }
+ }
+
+ public ConstructorInfo ConstructorInfo
+ {
+ get
+ {
+ return (ConstructorInfo)MethodInfo;
+ }
+ }
+ }
+
+ #endregion
+
+ #region class MappedParameter
+
+ ///
+ /// A parameter in a method or constructor of a mixed generic type.
+ ///
+ public class MappedParameter : IParameter
+ {
+ private MixedGenericType _parentType;
+ private ExternalParameter _baseParameter;
+
+ public MappedParameter(TypeSystemServices tss, ExternalParameter parameter, MixedGenericType parentType)
+ {
+ _parentType = parentType;
+ _baseParameter = parameter;
+ }
+
+ public bool IsByRef
+ {
+ get { return _baseParameter.IsByRef; }
+ }
+
+ public IType Type
+ {
+ get { return _parentType.MapType(_baseParameter.Type); }
+ }
+
+ public string Name
+ {
+ get { return _baseParameter.Name; }
+ }
+
+ public string FullName
+ {
+ get { return _baseParameter.FullName; }
+ }
+
+ public EntityType EntityType
+ {
+ get { return EntityType.Parameter; }
+ }
+ }
+
+ #endregion
+
+ #region class MappedProperty
+
+ public class MappedProperty : ExternalProperty
+ {
+ private MixedGenericType _parentType;
+
+ public MappedProperty(TypeSystemServices tss, PropertyInfo property, MixedGenericType parentType) : base(tss, property)
+ {
+ _parentType = parentType;
+ }
+
+ public override IType Type
+ {
+ get { return _parentType.MapType(base.Type); }
+ }
+
+ public override IType DeclaringType
+ {
+ get { return _parentType.MapType(base.DeclaringType); }
+ }
+
+ public override IParameter[] GetParameters()
+ {
+ IParameter[] baseParams = base.GetParameters();
+ return Array.ConvertAll(
+ baseParams,
+ delegate(IParameter p)
+ {
+ return new MappedParameter(_typeSystemServices, (ExternalParameter)p, _parentType);
+ });
+ }
+
+ public override IMethod GetGetMethod()
+ {
+ return (IMethod)_parentType.MapMember(base.GetGetMethod());
+ }
+
+ public override IMethod GetSetMethod()
+ {
+ return (IMethod)_parentType.MapMember(base.GetSetMethod());
+ }
+
+ public override string ToString()
+ {
+ IParameter[] parameters = GetParameters();
+ if (parameters.Length > 0)
+ {
+ string[] parameterNames = Array.ConvertAll(
+ parameters,
+ delegate(IParameter p) { return p.Type.Name; });
+
+ return string.Format(
+ "{0} {1} [{2}]",
+ Type.Name,
+ Name,
+ string.Join(", ", parameterNames));
+ }
+
+ return string.Format("{0} {1}", Type.Name, Name);
+ }
+ }
+ #endregion
+
+ #region class MappedField
+
+ public class MappedField : ExternalField
+ {
+ MixedGenericType _parentType;
+
+ public MappedField(TypeSystemServices tss, FieldInfo field, MixedGenericType parentType) : base(tss, field)
+ {
+ _parentType = parentType;
+ }
+
+ public override IType DeclaringType
+ {
+ get { return _parentType; }
+ }
+
+ public override IType Type
+ {
+ get { return _parentType.MapType(base.Type); }
+ }
+ }
+
+ #endregion
+ }
+
+ public class MixedGenericCallableType: MixedGenericType, ICallableType
+ {
+ ExternalCallableType _definition;
+ CallableSignature _signature;
+
+ public MixedGenericCallableType(TypeSystemServices tss, ExternalCallableType definition, IType[] arguments):
+ base(tss, definition, arguments)
+ {
+ _definition = definition;
+ }
+
+ public CallableSignature GetSignature()
+ {
+ if (_signature == null)
+ {
+ CallableSignature definitionSignature = _definition.GetSignature();
+
+ IParameter[] parameters = Array.ConvertAll(
+ definitionSignature.Parameters,
+ delegate(IParameter p)
+ {
+ return new MappedParameter(_typeSystemServices, (ExternalParameter)p, this);
+ });
+
+ _signature = new CallableSignature(parameters, MapType(definitionSignature.ReturnType));
+ }
+
+ return _signature;
+ }
+
+ override public bool IsAssignableFrom(IType other)
+ {
+ return _typeSystemServices.IsCallableTypeAssignableFrom(this, other);
+ }
+ }
+}
+
+#endif
Index: src/Boo.Lang.Compiler/TypeSystem/NameResolutionService.cs
===================================================================
--- src/Boo.Lang.Compiler/TypeSystem/NameResolutionService.cs (revision 2352)
+++ src/Boo.Lang.Compiler/TypeSystem/NameResolutionService.cs (working copy)
@@ -274,10 +274,14 @@
}
}
- private IEntity MakeGenericType(GenericTypeReference node, IGenericTypeDefinition entity)
+ private IEntity MakeGenericType(GenericTypeReference node, IType entity)
{
IType[] arguments = ResolveGenericArguments(node);
- return entity.MakeGenericType(arguments);
+ if (entity.GenericTypeDefinitionInfo == null)
+ {
+ throw CompilerErrorFactory.NotAGenericDefinition(node, node.Name);
+ }
+ return entity.GenericTypeDefinitionInfo.MakeGenericType(arguments);
}
private IType[] ResolveGenericArguments(GenericTypeReference node)
@@ -294,6 +298,7 @@
public void ResolveSimpleTypeReference(SimpleTypeReference node)
{
+
if (null != node.Entity) return;
IEntity entity = ResolveTypeName(node);
@@ -319,12 +324,14 @@
GenericTypeReference gtr = node as GenericTypeReference;
if (null != gtr)
{
- entity = MakeGenericType(gtr, (IGenericTypeDefinition) entity);
+ entity = MakeGenericType(gtr, (IType)entity);
}
#endif
+
node.Name = entity.FullName;
}
- node.Entity = entity;
+
+ node.Entity = entity;
}
private IEntity ResolveTypeName(SimpleTypeReference node)
Index: src/Boo.Lang.Compiler/TypeSystem/TypeSystemServices.cs
===================================================================
--- src/Boo.Lang.Compiler/TypeSystem/TypeSystemServices.cs (revision 2352)
+++ src/Boo.Lang.Compiler/TypeSystem/TypeSystemServices.cs (working copy)
@@ -1,1492 +1,1490 @@
-#region license
-// Copyright (c) 2004, Rodrigo B. de Oliveira (rbo@acm.org)
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without modification,
-// are permitted provided that the following conditions are met:
-//
-// * Redistributions of source code must retain the above copyright notice,
-// this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above copyright notice,
-// this list of conditions and the following disclaimer in the documentation
-// and/or other materials provided with the distribution.
-// * Neither the name of Rodrigo B. de Oliveira nor the names of its
-// contributors may be used to endorse or promote products derived from this
-// software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#endregion
-
-namespace Boo.Lang.Compiler.TypeSystem
-{
- using System;
- using System.Collections;
- using System.Reflection;
- using System.Text;
- using Boo.Lang.Compiler.Ast;
- using Attribute = Boo.Lang.Compiler.Ast.Attribute;
- using Module = Boo.Lang.Compiler.Ast.Module;
-
- public class TypeSystemServices
- {
- public DuckTypeImpl DuckType;
-
- public ExternalType IQuackFuType;
-
- public ExternalType ExceptionType;
-
- public ExternalType ApplicationExceptionType;
-
- public ExternalType MulticastDelegateType;
-
- public ExternalType DelegateType;
-
- public ExternalType IntPtrType;
-
- public ExternalType UIntPtrType;
-
- public ExternalType ObjectType;
-
- public ExternalType ValueTypeType;
-
- public ExternalType EnumType;
-
- public ExternalType RegexType;
-
- public ExternalType ArrayType;
-
- public ExternalType TypeType;
-
- public IArrayType ObjectArrayType;
-
- public ExternalType VoidType;
-
- public ExternalType StringType;
-
- public ExternalType BoolType;
-
- public ExternalType CharType;
-
- public ExternalType SByteType;
-
- public ExternalType ByteType;
-
- public ExternalType ShortType;
-
- public ExternalType UShortType;
-
- public ExternalType IntType;
-
- public ExternalType UIntType;
-
- public ExternalType LongType;
-
- public ExternalType ULongType;
-
- public ExternalType SingleType;
-
- public ExternalType DoubleType;
-
- public ExternalType DecimalType;
-
- public ExternalType TimeSpanType;
-
- public ExternalType DateTimeType;
-
- public ExternalType RuntimeServicesType;
-
- public ExternalType BuiltinsType;
-
- public ExternalType ListType;
-
- public ExternalType HashType;
-
- public ExternalType ICallableType;
-
- public ExternalType IEnumerableType;
-
- public ExternalType IEnumeratorType;
-
- public ExternalType ICollectionType;
-
- public ExternalType IListType;
-
- public ExternalType IDictionaryType;
-
- public ExternalType SystemAttribute;
-
- protected Hashtable _primitives = new Hashtable();
-
- protected Hashtable _entityCache = new Hashtable();
-
- protected Hashtable _arrayCache = new Hashtable();
-
- protected Hashtable _anonymousCallableTypes = new Hashtable();
-
- public static readonly IType ErrorEntity = Error.Default;
-
- public readonly BooCodeBuilder CodeBuilder;
-
- StringBuilder _buffer = new StringBuilder();
-
- Module _compilerGeneratedTypesModule;
-
- Module _compilerGeneratedExtensionsModule;
-
- ClassDefinition _compilerGeneratedExtensionsClass;
-
- CompilerContext _context;
-
- public TypeSystemServices() : this(new CompilerContext())
- {
- }
-
- public TypeSystemServices(CompilerContext context)
- {
- if (null == context)
- {
- throw new ArgumentNullException("context");
- }
-
- _context = context;
-
- CodeBuilder = new BooCodeBuilder(this);
-
- Cache(typeof(Builtins.duck), DuckType = new DuckTypeImpl(this));
- Cache(IQuackFuType = new ExternalType(this, typeof(IQuackFu)));
- Cache(VoidType = new VoidTypeImpl(this));
- Cache(ObjectType = new ExternalType(this, Types.Object));
- Cache(RegexType = new ExternalType(this, Types.Regex));
- Cache(ValueTypeType = new ExternalType(this, typeof(ValueType)));
- Cache(EnumType = new ExternalType(this, typeof(Enum)));
- Cache(ArrayType = new ExternalType(this, Types.Array));
- Cache(TypeType = new ExternalType(this, Types.Type));
- Cache(StringType = new ExternalType(this, Types.String));
- Cache(BoolType = new ExternalType(this, Types.Bool));
- Cache(SByteType = new ExternalType(this, Types.SByte));
- Cache(CharType = new ExternalType(this, Types.Char));
- Cache(ShortType = new ExternalType(this, Types.Short));
- Cache(IntType = new ExternalType(this, Types.Int));
- Cache(LongType = new ExternalType(this, Types.Long));
- Cache(ByteType = new ExternalType(this, Types.Byte));
- Cache(UShortType = new ExternalType(this, Types.UShort));
- Cache(UIntType = new ExternalType(this, Types.UInt));
- Cache(ULongType = new ExternalType(this, Types.ULong));
- Cache(SingleType = new ExternalType(this, Types.Single));
- Cache(DoubleType = new ExternalType(this, Types.Double));
- Cache(DecimalType = new ExternalType(this, Types.Decimal));
- Cache(TimeSpanType = new ExternalType(this, Types.TimeSpan));
- Cache(DateTimeType = new ExternalType(this, Types.DateTime));
- Cache(RuntimeServicesType = new ExternalType(this, Types.RuntimeServices));
- Cache(BuiltinsType = new ExternalType(this, Types.Builtins));
- Cache(ListType = new ExternalType(this, Types.List));
- Cache(HashType = new ExternalType(this, Types.Hash));
- Cache(ICallableType = new ExternalType(this, Types.ICallable));
- Cache(IEnumerableType = new ExternalType(this, Types.IEnumerable));
- Cache(IEnumeratorType = new ExternalType(this, typeof(IEnumerator)));
- Cache(ICollectionType = new ExternalType(this, Types.ICollection));
- Cache(IListType = new ExternalType(this, Types.IList));
- Cache(IDictionaryType = new ExternalType(this, Types.IDictionary));
- Cache(ApplicationExceptionType = new ExternalType(this, Types.ApplicationException));
- Cache(ExceptionType = new ExternalType(this, Types.Exception));
- Cache(IntPtrType = new ExternalType(this, Types.IntPtr));
- Cache(UIntPtrType = new ExternalType(this, Types.UIntPtr));
- Cache(MulticastDelegateType = new ExternalType(this, Types.MulticastDelegate));
- Cache(DelegateType = new ExternalType(this, Types.Delegate));
- Cache(SystemAttribute = new ExternalType(this, typeof(System.Attribute)));
-
- ObjectArrayType = GetArrayType(ObjectType, 1);
-
- PreparePrimitives();
- PrepareBuiltinFunctions();
- }
-
- public CompilerContext Context
- {
- get
- {
- return _context;
- }
- }
-
- public IType GetMostGenericType(IType current, IType candidate)
- {
- if (current.IsAssignableFrom(candidate))
- {
- return current;
- }
-
- if (candidate.IsAssignableFrom(current))
- {
- return candidate;
- }
-
- if (IsNumberOrBool(current) && IsNumberOrBool(candidate))
- {
- return GetPromotedNumberType(current, candidate);
- }
-
- if (IsCallableType(current) && IsCallableType(candidate))
- {
- return ICallableType;
- }
-
- if (current.IsClass && candidate.IsClass)
- {
- if (current == ObjectType || candidate == ObjectType)
- {
- return ObjectType;
- }
- if (current.GetTypeDepth() < candidate.GetTypeDepth())
- {
- return GetMostGenericType(current.BaseType, candidate);
- }
- return GetMostGenericType(current, candidate.BaseType);
- }
- return ObjectType;
- }
-
- public IType GetPromotedNumberType(IType left, IType right)
- {
- if (left == DecimalType ||
- right == DecimalType)
- {
- return DecimalType;
- }
- if (left == DoubleType ||
- right == DoubleType)
- {
- return DoubleType;
- }
- if (left == SingleType ||
- right == SingleType)
- {
- return SingleType;
- }
- if (left == ULongType)
- {
- if (right == SByteType ||
- right == ShortType ||
- right == IntType ||
- right == LongType)
- {
- // This is against the C# spec but allows expressions like:
- // ulong x = 4
- // y = x + 1
- // y will be long.
- // C# disallows mixing ulongs and signed numbers
- // but in the above case it promotes the constant to ulong
- // and the result is ulong.
- // Since its too late here to promote the constant,
- // maybe we should return LongType. I didn't chose ULongType
- // because in other cases returns .
- return LongType;
- }
- return ULongType;
- }
- if (right == ULongType)
- {
- if (left == SByteType ||
- left == ShortType ||
- left == IntType ||
- left == LongType)
- {
- // This is against the C# spec but allows expressions like:
- // ulong x = 4
- // y = 1 + x
- // y will be long.
- // C# disallows mixing ulongs and signed numbers
- // but in the above case it promotes the constant to ulong
- // and the result is ulong.
- // Since its too late here to promote the constant,
- // maybe we should return LongType. I didn't chose ULongType
- // because in other cases returns .
- return LongType;
- }
- return ULongType;
- }
- if (left == LongType ||
- right == LongType)
- {
- return LongType;
- }
- if (left == UIntType)
- {
- if (right == SByteType ||
- right == ShortType ||
- right == IntType)
- {
- // This is allowed per C# spec and y is long:
- // uint x = 4
- // y = x + 1
- // C# promotes to also
- // but in the above case it promotes the constant to uint first
- // and the result of "x + 1" is uint.
- // Since its too late here to promote the constant,
- // "y = x + 1" will be long in boo.
- return LongType;
- }
- return UIntType;
- }
- if (right == UIntType)
- {
- if (left == SByteType ||
- left == ShortType ||
- left == IntType)
- {
- // This is allowed per C# spec and y is long:
- // uint x = 4
- // y = 1 + x
- // C# promotes to also
- // but in the above case it promotes the constant to uint first
- // and the result of "1 + x" is uint.
- // Since its too late here to promote the constant,
- // "y = x + 1" will be long in boo.
- return LongType;
- }
- return UIntType;
- }
- if (left == IntType ||
- right == IntType ||
- left == ShortType ||
- right == ShortType ||
- left == UShortType ||
- right == UShortType ||
- left == ByteType ||
- right == ByteType ||
- left == SByteType ||
- right == SByteType)
- {
- return IntType;
- }
- return left;
- }
-
- public static bool IsReadOnlyField(IField field)
- {
- return field.IsInitOnly || field.IsLiteral;
- }
-
- public bool IsCallable(IType type)
- {
- return (TypeType == type) || IsCallableType(type) || IsDuckType(type);
- }
-
- public bool IsDuckTyped(Expression expression)
- {
- IType type = expression.ExpressionType;
- return null != type && this.IsDuckType(type);
- }
-
- public bool IsQuackBuiltin(Expression node)
- {
- return IsQuackBuiltin(GetOptionalEntity(node));
- }
-
- public bool IsQuackBuiltin(IEntity entity)
- {
- return BuiltinFunction.Quack == entity;
- }
-
- public bool IsDuckType(IType type)
- {
- if (null == type)
- {
- throw new ArgumentNullException("type");
- }
- return (
- (type == DuckType)
- || KnowsQuackFu(type)
- || (_context.Parameters.Ducky
- && (type == ObjectType)));
+#region license
+// Copyright (c) 2004, Rodrigo B. de Oliveira (rbo@acm.org)
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+// * Neither the name of Rodrigo B. de Oliveira nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#endregion
+
+namespace Boo.Lang.Compiler.TypeSystem
+{
+ using System;
+ using System.Collections;
+ using System.Reflection;
+ using System.Text;
+ using Boo.Lang.Compiler.Ast;
+ using Attribute = Boo.Lang.Compiler.Ast.Attribute;
+ using Module = Boo.Lang.Compiler.Ast.Module;
+
+ public class TypeSystemServices
+ {
+ public DuckTypeImpl DuckType;
+
+ public ExternalType IQuackFuType;
+
+ public ExternalType ExceptionType;
+
+ public ExternalType ApplicationExceptionType;
+
+ public ExternalType MulticastDelegateType;
+
+ public ExternalType DelegateType;
+
+ public ExternalType IntPtrType;
+
+ public ExternalType UIntPtrType;
+
+ public ExternalType ObjectType;
+
+ public ExternalType ValueTypeType;
+
+ public ExternalType EnumType;
+
+ public ExternalType RegexType;
+
+ public ExternalType ArrayType;
+
+ public ExternalType TypeType;
+
+ public IArrayType ObjectArrayType;
+
+ public ExternalType VoidType;
+
+ public ExternalType StringType;
+
+ public ExternalType BoolType;
+
+ public ExternalType CharType;
+
+ public ExternalType SByteType;
+
+ public ExternalType ByteType;
+
+ public ExternalType ShortType;
+
+ public ExternalType UShortType;
+
+ public ExternalType IntType;
+
+ public ExternalType UIntType;
+
+ public ExternalType LongType;
+
+ public ExternalType ULongType;
+
+ public ExternalType SingleType;
+
+ public ExternalType DoubleType;
+
+ public ExternalType DecimalType;
+
+ public ExternalType TimeSpanType;
+
+ public ExternalType DateTimeType;
+
+ public ExternalType RuntimeServicesType;
+
+ public ExternalType BuiltinsType;
+
+ public ExternalType ListType;
+
+ public ExternalType HashType;
+
+ public ExternalType ICallableType;
+
+ public ExternalType IEnumerableType;
+
+ public ExternalType IEnumeratorType;
+
+ public ExternalType ICollectionType;
+
+ public ExternalType IListType;
+
+ public ExternalType IDictionaryType;
+
+ public ExternalType SystemAttribute;
+
+ protected Hashtable _primitives = new Hashtable();
+
+ protected Hashtable _entityCache = new Hashtable();
+
+ protected Hashtable _arrayCache = new Hashtable();
+
+ protected Hashtable _anonymousCallableTypes = new Hashtable();
+
+ public static readonly IType ErrorEntity = Error.Default;
+
+ public readonly BooCodeBuilder CodeBuilder;
+
+ StringBuilder _buffer = new StringBuilder();
+
+ Module _compilerGeneratedTypesModule;
+
+ Module _compilerGeneratedExtensionsModule;
+
+ ClassDefinition _compilerGeneratedExtensionsClass;
+
+ CompilerContext _context;
+
+ public TypeSystemServices() : this(new CompilerContext())
+ {
}
+
+ public TypeSystemServices(CompilerContext context)
+ {
+ if (null == context)
+ {
+ throw new ArgumentNullException("context");
+ }
+
+ _context = context;
+ CodeBuilder = new BooCodeBuilder(this);
+
+ Cache(typeof(Builtins.duck), DuckType = new DuckTypeImpl(this));
+ Cache(IQuackFuType = new ExternalType(this, typeof(IQuackFu)));
+ Cache(VoidType = new VoidTypeImpl(this));
+ Cache(ObjectType = new ExternalType(this, Types.Object));
+ Cache(RegexType = new ExternalType(this, Types.Regex));
+ Cache(ValueTypeType = new ExternalType(this, typeof(ValueType)));
+ Cache(EnumType = new ExternalType(this, typeof(Enum)));
+ Cache(ArrayType = new ExternalType(this, Types.Array));
+ Cache(TypeType = new ExternalType(this, Types.Type));
+ Cache(StringType = new ExternalType(this, Types.String));
+ Cache(BoolType = new ExternalType(this, Types.Bool));
+ Cache(SByteType = new ExternalType(this, Types.SByte));
+ Cache(CharType = new ExternalType(this, Types.Char));
+ Cache(ShortType = new ExternalType(this, Types.Short));
+ Cache(IntType = new ExternalType(this, Types.Int));
+ Cache(LongType = new ExternalType(this, Types.Long));
+ Cache(ByteType = new ExternalType(this, Types.Byte));
+ Cache(UShortType = new ExternalType(this, Types.UShort));
+ Cache(UIntType = new ExternalType(this, Types.UInt));
+ Cache(ULongType = new ExternalType(this, Types.ULong));
+ Cache(SingleType = new ExternalType(this, Types.Single));
+ Cache(DoubleType = new ExternalType(this, Types.Double));
+ Cache(DecimalType = new ExternalType(this, Types.Decimal));
+ Cache(TimeSpanType = new ExternalType(this, Types.TimeSpan));
+ Cache(DateTimeType = new ExternalType(this, Types.DateTime));
+ Cache(RuntimeServicesType = new ExternalType(this, Types.RuntimeServices));
+ Cache(BuiltinsType = new ExternalType(this, Types.Builtins));
+ Cache(ListType = new ExternalType(this, Types.List));
+ Cache(HashType = new ExternalType(this, Types.Hash));
+ Cache(ICallableType = new ExternalType(this, Types.ICallable));
+ Cache(IEnumerableType = new ExternalType(this, Types.IEnumerable));
+ Cache(IEnumeratorType = new ExternalType(this, typeof(IEnumerator)));
+ Cache(ICollectionType = new ExternalType(this, Types.ICollection));
+ Cache(IListType = new ExternalType(this, Types.IList));
+ Cache(IDictionaryType = new ExternalType(this, Types.IDictionary));
+ Cache(ApplicationExceptionType = new ExternalType(this, Types.ApplicationException));
+ Cache(ExceptionType = new ExternalType(this, Types.Exception));
+ Cache(IntPtrType = new ExternalType(this, Types.IntPtr));
+ Cache(UIntPtrType = new ExternalType(this, Types.UIntPtr));
+ Cache(MulticastDelegateType = new ExternalType(this, Types.MulticastDelegate));
+ Cache(DelegateType = new ExternalType(this, Types.Delegate));
+ Cache(SystemAttribute = new ExternalType(this, typeof(System.Attribute)));
+
+ ObjectArrayType = GetArrayType(ObjectType, 1);
+
+ PreparePrimitives();
+ PrepareBuiltinFunctions();
+ }
+
+ public CompilerContext Context
+ {
+ get
+ {
+ return _context;
+ }
+ }
+
+ public IType GetMostGenericType(IType current, IType candidate)
+ {
+ if (current.IsAssignableFrom(candidate))
+ {
+ return current;
+ }
+
+ if (candidate.IsAssignableFrom(current))
+ {
+ return candidate;
+ }
+
+ if (IsNumberOrBool(current) && IsNumberOrBool(candidate))
+ {
+ return GetPromotedNumberType(current, candidate);
+ }
+
+ if (IsCallableType(current) && IsCallableType(candidate))
+ {
+ return ICallableType;
+ }
+
+ if (current.IsClass && candidate.IsClass)
+ {
+ if (current == ObjectType || candidate == ObjectType)
+ {
+ return ObjectType;
+ }
+ if (current.GetTypeDepth() < candidate.GetTypeDepth())
+ {
+ return GetMostGenericType(current.BaseType, candidate);
+ }
+ return GetMostGenericType(current, candidate.BaseType);
+ }
+ return ObjectType;
+ }
+
+ public IType GetPromotedNumberType(IType left, IType right)
+ {
+ if (left == DecimalType ||
+ right == DecimalType)
+ {
+ return DecimalType;
+ }
+ if (left == DoubleType ||
+ right == DoubleType)
+ {
+ return DoubleType;
+ }
+ if (left == SingleType ||
+ right == SingleType)
+ {
+ return SingleType;
+ }
+ if (left == ULongType)
+ {
+ if (right == SByteType ||
+ right == ShortType ||
+ right == IntType ||
+ right == LongType)
+ {
+ // This is against the C# spec but allows expressions like:
+ // ulong x = 4
+ // y = x + 1
+ // y will be long.
+ // C# disallows mixing ulongs and signed numbers
+ // but in the above case it promotes the constant to ulong
+ // and the result is ulong.
+ // Since its too late here to promote the constant,
+ // maybe we should return LongType. I didn't chose ULongType
+ // because in other cases returns .
+ return LongType;
+ }
+ return ULongType;
+ }
+ if (right == ULongType)
+ {
+ if (left == SByteType ||
+ left == ShortType ||
+ left == IntType ||
+ left == LongType)
+ {
+ // This is against the C# spec but allows expressions like:
+ // ulong x = 4
+ // y = 1 + x
+ // y will be long.
+ // C# disallows mixing ulongs and signed numbers
+ // but in the above case it promotes the constant to ulong
+ // and the result is ulong.
+ // Since its too late here to promote the constant,
+ // maybe we should return LongType. I didn't chose ULongType
+ // because in other cases returns .
+ return LongType;
+ }
+ return ULongType;
+ }
+ if (left == LongType ||
+ right == LongType)
+ {
+ return LongType;
+ }
+ if (left == UIntType)
+ {
+ if (right == SByteType ||
+ right == ShortType ||
+ right == IntType)
+ {
+ // This is allowed per C# spec and y is long:
+ // uint x = 4
+ // y = x + 1
+ // C# promotes to also
+ // but in the above case it promotes the constant to uint first
+ // and the result of "x + 1" is uint.
+ // Since its too late here to promote the constant,
+ // "y = x + 1" will be long in boo.
+ return LongType;
+ }
+ return UIntType;
+ }
+ if (right == UIntType)
+ {
+ if (left == SByteType ||
+ left == ShortType ||
+ left == IntType)
+ {
+ // This is allowed per C# spec and y is long:
+ // uint x = 4
+ // y = 1 + x
+ // C# promotes to also
+ // but in the above case it promotes the constant to uint first
+ // and the result of "1 + x" is uint.
+ // Since its too late here to promote the constant,
+ // "y = x + 1" will be long in boo.
+ return LongType;
+ }
+ return UIntType;
+ }
+ if (left == IntType ||
+ right == IntType ||
+ left == ShortType ||
+ right == ShortType ||
+ left == UShortType ||
+ right == UShortType ||
+ left == ByteType ||
+ right == ByteType ||
+ left == SByteType ||
+ right == SByteType)
+ {
+ return IntType;
+ }
+ return left;
+ }
+
+ public static bool IsReadOnlyField(IField field)
+ {
+ return field.IsInitOnly || field.IsLiteral;
+ }
+
+ public bool IsCallable(IType type)
+ {
+ return (TypeType == type) || IsCallableType(type) || IsDuckType(type);
+ }
+
+ public bool IsDuckTyped(Expression expression)
+ {
+ IType type = expression.ExpressionType;
+ return null != type && this.IsDuckType(type);
+ }
+
+ public bool IsQuackBuiltin(Expression node)
+ {
+ return IsQuackBuiltin(GetOptionalEntity(node));
+ }
+
+ public bool IsQuackBuiltin(IEntity entity)
+ {
+ return BuiltinFunction.Quack == entity;
+ }
+
+ public bool IsDuckType(IType type)
+ {
+ if (null == type)
+ {
+ throw new ArgumentNullException("type");
+ }
+ return (
+ (type == DuckType)
+ || KnowsQuackFu(type)
+ || (_context.Parameters.Ducky
+ && (type == ObjectType)));
+ }
+
public bool KnowsQuackFu(IType type)
{
return type.IsSubclassOf(IQuackFuType);
- }
-
- bool IsCallableType(IType type)
- {
- return (ICallableType.IsAssignableFrom(type)) ||
- (type is ICallableType);
- }
-
- public AnonymousCallableType GetCallableType(IMethod method)
- {
- CallableSignature signature = new CallableSignature(method);
- return GetCallableType(signature);
- }
-
- public AnonymousCallableType GetCallableType(CallableSignature signature)
- {
- AnonymousCallableType type = (AnonymousCallableType)_anonymousCallableTypes[signature];
- if (null == type)
- {
- type = new AnonymousCallableType(this, signature);
- _anonymousCallableTypes.Add(signature, type);
- }
- return type;
- }
-
- public IType GetConcreteCallableType(Node sourceNode, CallableSignature signature)
- {
- AnonymousCallableType type = GetCallableType(signature);
- return GetConcreteCallableType(sourceNode, type);
- }
-
- public IType GetEnumeratorItemType(IType iteratorType)
- {
- if (iteratorType.IsArray) return ((IArrayType)iteratorType).GetElementType();
- if (StringType == iteratorType) return CharType;
-
- if (iteratorType.IsClass)
- {
- IType enumeratorItemType = GetEnumeratorItemTypeFromAttribute(iteratorType);
- if (null != enumeratorItemType)
- {
- return enumeratorItemType;
- }
-
-#if NET_2_0
- enumeratorItemType = GetEnumeratorItemTypeFromGenericEnumerable(iteratorType);
- if (null != enumeratorItemType)
- {
- return enumeratorItemType;
- }
-#endif
- }
- return ObjectType;
- }
-
- public IType GetExpressionType(Expression node)
- {
- IType type = node.ExpressionType;
- if (null == type)
- {
- throw CompilerErrorFactory.InvalidNode(node);
- }
- return type;
- }
-
- public IType GetConcreteExpressionType(Expression expression)
- {
- IType type = GetExpressionType(expression);
- AnonymousCallableType anonymousType = type as AnonymousCallableType;
- if (null != anonymousType)
- {
- IType concreteType = GetConcreteCallableType(expression, anonymousType);
- expression.ExpressionType = concreteType;
- return concreteType;
- }
- return type;
- }
-
- public void MapToConcreteExpressionTypes(ExpressionCollection items)
- {
- foreach (Expression item in items)
- {
- GetConcreteExpressionType(item);
- }
- }
-
- public ClassDefinition GetCompilerGeneratedExtensionsClass()
- {
- if (null == _compilerGeneratedExtensionsClass)
- {
- BooClassBuilder builder = CodeBuilder.CreateClass("CompilerGeneratedExtensions");
- builder.Modifiers = TypeMemberModifiers.Final|TypeMemberModifiers.Transient|TypeMemberModifiers.Public;
- builder.AddBaseType(ObjectType);
-
- BooMethodBuilder ctor = builder.AddConstructor();
- ctor.Modifiers = TypeMemberModifiers.Private;
- ctor.Body.Add(
- CodeBuilder.CreateSuperConstructorInvocation(ObjectType));
-
- ClassDefinition cd = builder.ClassDefinition;
- Module module = GetCompilerGeneratedExtensionsModule();
- module.Members.Add(cd);
- ((ModuleEntity)module.Entity).InitializeModuleClass(cd);
-
- _compilerGeneratedExtensionsClass = cd;
- }
- return _compilerGeneratedExtensionsClass;
- }
-
- public Module GetCompilerGeneratedExtensionsModule()
- {
- if (null == _compilerGeneratedExtensionsModule)
- {
- _compilerGeneratedExtensionsModule = NewModule(null);
- }
- return _compilerGeneratedExtensionsModule;
- }
-
- public void AddCompilerGeneratedType(TypeDefinition type)
- {
- GetCompilerGeneratedTypesModule().Members.Add(type);
- }
-
- public Module GetCompilerGeneratedTypesModule()
- {
- if (null == _compilerGeneratedTypesModule)
- {
- _compilerGeneratedTypesModule = NewModule("CompilerGenerated");
- }
- return _compilerGeneratedTypesModule;
- }
-
- private Module NewModule(string ns)
- {
- Module module = new Module();
- if (null != ns) module.Namespace = new NamespaceDeclaration(ns);
- module.Entity = new ModuleEntity(_context.NameResolutionService, this, module);
- _context.CompileUnit.Modules.Add(module);
- return module;
- }
-
- public ClassDefinition CreateCallableDefinition(string name)
- {
- ClassDefinition cd = new ClassDefinition();
- cd.BaseTypes.Add(CodeBuilder.CreateTypeReference(this.MulticastDelegateType));
- cd.BaseTypes.Add(CodeBuilder.CreateTypeReference(this.ICallableType));
- cd.Name = name;
- cd.Modifiers = TypeMemberModifiers.Final;
- cd.Members.Add(CreateCallableConstructor());
- cd.Members.Add(CreateCallMethod());
- cd.Entity = new InternalCallableType(this, cd);
- return cd;
- }
-
- Method CreateCallMethod()
- {
- Method method = new Method("Call");
- method.Modifiers = TypeMemberModifiers.Public|TypeMemberModifiers.Virtual;
- method.Parameters.Add(CodeBuilder.CreateParameterDeclaration(1, "args", ObjectArrayType));
- method.ReturnType = CodeBuilder.CreateTypeReference(ObjectType);
- method.Entity = new InternalMethod(this, method);
- return method;
- }
-
- Constructor CreateCallableConstructor()
- {
- Constructor constructor = new Constructor();
- constructor.Modifiers = TypeMemberModifiers.Public;
- constructor.ImplementationFlags = MethodImplementationFlags.Runtime;
- constructor.Parameters.Add(
- CodeBuilder.CreateParameterDeclaration(1, "instance", ObjectType));
- constructor.Parameters.Add(
- CodeBuilder.CreateParameterDeclaration(2, "method", IntPtrType));
- constructor.Entity = new InternalConstructor(this, constructor);
- return constructor;
- }
-
- public bool AreTypesRelated(IType lhs, IType rhs)
- {
- ICallableType ctype = lhs as ICallableType;
- if (null != ctype)
- {
- return ctype.IsAssignableFrom(rhs)
- || ctype.IsSubclassOf(rhs);
- }
- return lhs.IsAssignableFrom(rhs)
- || (lhs.IsInterface && !rhs.IsFinal)
- || (rhs.IsInterface && !lhs.IsFinal)
- || CanBeReachedByDownCastOrPromotion(lhs, rhs)
- || FindImplicitConversionOperator(rhs,lhs) != null;
- }
-
- public IMethod FindExplicitConversionOperator(IType fromType, IType toType)
- {
- return FindConversionOperator("op_Explicit", fromType, toType);
- }
-
- public IMethod FindImplicitConversionOperator(IType fromType, IType toType)
- {
- return FindConversionOperator("op_Implicit", fromType, toType);
- }
-
- public IMethod FindConversionOperator(string name, IType fromType, IType toType)
- {
- while (fromType != this.ObjectType)
- {
- IMethod method = FindConversionOperator(name, fromType, toType, fromType.GetMembers());
- if (null != method) return method;
- method = FindConversionOperator(name, fromType, toType, toType.GetMembers());
- if (null != method) return method;
- method = FindConversionOperator(name, fromType, toType, FindExtension(fromType, name));
- if (null != method) return method;
-
- fromType = fromType.BaseType;
- if (null == fromType) break;
- }
- return null;
- }
-
- private IEntity[] FindExtension(IType fromType, string name)
- {
- IEntity extension = _context.NameResolutionService.ResolveExtension(fromType, name);
- if (null == extension) return Ambiguous.NoEntities;
-
- Ambiguous a = extension as Ambiguous;
- if (null != a) return a.Entities;
- return new IEntity[] { extension };
- }
-
- IMethod FindConversionOperator(string name, IType fromType, IType toType, IEntity[] candidates)
- {
- foreach (IEntity entity in candidates)
- {
- if (EntityType.Method != entity.EntityType || name != entity.Name) continue;
- IMethod method = (IMethod)entity;
- if (IsConversionOperator(method, fromType, toType)) return method;
- }
- return null;
- }
-
- bool IsConversionOperator(IMethod method, IType fromType, IType toType)
- {
- if (!method.IsStatic) return false;
- if (method.ReturnType != toType) return false;
- IParameter[] parameters = method.GetParameters();
- return (1 == parameters.Length && fromType == parameters[0].Type);
- }
-
- public bool IsCallableTypeAssignableFrom(ICallableType lhs, IType rhs)
- {
- if (lhs == rhs || Null.Default == rhs)
- {
- return true;
- }
-
- ICallableType other = rhs as ICallableType;
- if (null != other)
- {
- CallableSignature lvalue = lhs.GetSignature();
- CallableSignature rvalue = other.GetSignature();
- if (lvalue == rvalue)
- {
- return true;
- }
-
- IParameter[] lparams = lvalue.Parameters;
- IParameter[] rparams = rvalue.Parameters;
- if (lparams.Length >= rparams.Length)
- {
- for (int i=0; i 1)
- {
- IEntity[] tags = new IEntity[info.Length];
- for (int i=0; i 0)
- {
- return Map(info[0]);
- }
- return null;
- }
-
- public IEntity Map(MemberInfo mi)
- {
- IEntity tag = (IEntity)_entityCache[GetCacheKey(mi)];
- if (null == tag)
- {
- switch (mi.MemberType)
- {
- case MemberTypes.Method:
- {
- return Map((MethodInfo)mi);
- }
-
- case MemberTypes.Constructor:
- {
- return Map((ConstructorInfo)mi);
- }
-
- case MemberTypes.Field:
- {
- tag = new ExternalField(this, (FieldInfo)mi);
- break;
- }
-
- case MemberTypes.Property:
- {
- tag = new ExternalProperty(this, (PropertyInfo)mi);
- break;
- }
-
- case MemberTypes.Event:
- {
- tag = new ExternalEvent(this, (EventInfo)mi);
- break;
- }
-
- case MemberTypes.NestedType:
- {
- return Map((Type)mi);
- }
-
- default:
- {
- throw new NotImplementedException(mi.ToString());
- }
- }
- _entityCache.Add(GetCacheKey(mi), tag);
- }
- return tag;
- }
-
- public string GetSignature(IEntityWithParameters method)
- {
- return GetSignature(method, true);
- }
-
- public string GetSignature(IEntityWithParameters method, bool includeFullName)
- {
- _buffer.Length = 0;
- if (includeFullName)
- {
- _buffer.Append(method.FullName);
- }
- else
- {
- _buffer.Append(method.Name);
- }
- _buffer.Append("(");
-
- IParameter[] parameters = method.GetParameters();
- for (int i=0; i 0) { _buffer.Append(", "); }
- if (method.AcceptVarArgs && i == parameters.Length-1) { _buffer.Append('*'); }
- _buffer.Append(parameters[i].Type);
- }
- _buffer.Append(")");
- return _buffer.ToString();
- }
-
- public object GetCacheKey(MemberInfo mi)
- {
- return mi;
- }
-
- public IEntity ResolvePrimitive(string name)
- {
- return (IEntity)_primitives[name];
- }
-
- public bool IsPrimitive(string name)
- {
- return _primitives.ContainsKey(name);
- }
-
- ///
- /// checks if the passed type will be equivalente to
- /// System.Object in runtime (accounting for the presence
- /// of duck typing).
- ///
- public bool IsSystemObject(IType type)
- {
- return type == ObjectType || type == DuckType;
- }
-
- protected virtual void PreparePrimitives()
- {
- AddPrimitiveType("duck", DuckType);
- AddPrimitiveType("void", VoidType);
- AddPrimitiveType("bool", BoolType);
- AddPrimitiveType("char", CharType);
- AddPrimitiveType("date", DateTimeType);
- AddPrimitiveType("timespan", TimeSpanType);
- AddPrimitiveType("string", StringType);
- AddPrimitiveType("object", ObjectType);
- AddPrimitiveType("regex", RegexType);
- AddPrimitiveType("sbyte", SByteType);
- AddPrimitiveType("byte", ByteType);
- AddPrimitiveType("short", ShortType);
- AddPrimitiveType("ushort", UShortType);
- AddPrimitiveType("int", IntType);
- AddPrimitiveType("uint", UIntType);
- AddPrimitiveType("long", LongType);
- AddPrimitiveType("ulong", ULongType);
- AddPrimitiveType("single", SingleType);
- AddPrimitiveType("double", DoubleType);
- AddPrimitiveType("decimal", DecimalType);
- AddPrimitiveType("callable", ICallableType);
- }
-
- protected virtual void PrepareBuiltinFunctions()
- {
- AddBuiltin(BuiltinFunction.Len);
- AddBuiltin(BuiltinFunction.AddressOf);
- AddBuiltin(BuiltinFunction.Eval);
- AddBuiltin(BuiltinFunction.Switch);
- }
-
- protected void AddPrimitiveType(string name, ExternalType type)
- {
- _primitives[name] = type;
- type.PrimitiveName = name;
- }
-
- protected void AddBuiltin(BuiltinFunction function)
- {
- _primitives[function.Name] = function;
- }
-
- void Cache(ExternalType tag)
- {
- _entityCache[tag.ActualType] = tag;
- }
-
- void Cache(object key, IType tag)
- {
- _entityCache[key] = tag;
- }
-
- Method CreateBeginInvokeMethod(ICallableType anonymousType)
- {
- Method method = CodeBuilder.CreateRuntimeMethod("BeginInvoke", Map(typeof(IAsyncResult)),
- anonymousType.GetSignature().Parameters, false);
-
- int delta=method.Parameters.Count;
- method.Parameters.Add(
- CodeBuilder.CreateParameterDeclaration(delta+1, "callback", Map(typeof(AsyncCallback))));
- method.Parameters.Add(
- CodeBuilder.CreateParameterDeclaration(delta+1, "asyncState", ObjectType));
- return method;
- }
-
- Method CreateBeginInvokeExtension(ICallableType anonymousType, Method beginInvoke, out MethodInvocationExpression mie)
- {
- InternalMethod beginInvokeEntity = (InternalMethod)beginInvoke.Entity;
-
- Method extension = CodeBuilder.CreateMethod("BeginInvoke", Map(typeof(IAsyncResult)),
- TypeMemberModifiers.Public|TypeMemberModifiers.Static);
- extension.Attributes.Add(CodeBuilder.CreateAttribute(Types.ExtensionAttribute));
-
- ParameterDeclaration self = CodeBuilder.CreateParameterDeclaration(0, "self", beginInvokeEntity.DeclaringType);
-
- extension.Parameters.Add(self);
- CodeBuilder.DeclareParameters(extension, 1, anonymousType.GetSignature().Parameters);
-
- mie = CodeBuilder.CreateMethodInvocation(
- CodeBuilder.CreateReference(self),
- beginInvokeEntity);
-
- ParameterDeclarationCollection parameters = extension.Parameters;
- for (int i=1; i));
-
- IType itemType = null;
- foreach (IGenericType type in FindConstructedTypes(iteratorType, genericEnumerable))
- {
- IType candidateItemType = type.GetGenericArguments()[0];
- _context.TraceVerbose("Candidate enumerable item type for {0}: {1}",
- iteratorType, candidateItemType);
-
- if (itemType != null)
- {
- itemType = GetMostGenericType(itemType, candidateItemType);
- }
- else
- {
- itemType = candidateItemType;
- }
- }
-
- return itemType;
- }
-
- System.Collections.Generic.IEnumerable FindConstructedTypes(IType type, IGenericTypeDefinition genericTypeDef)
- {
- while (type != null)
- {
- string typeName = (type is ExternalType ? ((ExternalType)type).ActualType.Name : type.Name);
-
- IGenericType genericType = type as IGenericType;
-
- if (genericType != null &&
- genericType.FullyConstructed &&
- genericType.GetGenericTypeDefinition() == genericTypeDef)
- {
- yield return genericType;
- }
-
- foreach (IType interfaceType in type.GetInterfaces())
- {
- foreach (IGenericType match in FindConstructedTypes(interfaceType, genericTypeDef))
- {
- yield return match;
- }
- }
-
- type = type.BaseType;
- }
- }
-#endif
-
- public virtual IType GetConcreteCallableType(Node sourceNode, AnonymousCallableType anonymousType)
- {
- if (null == anonymousType.ConcreteType)
- {
- anonymousType.ConcreteType = CreateConcreteCallableType(sourceNode, anonymousType);
- }
- return anonymousType.ConcreteType;
- }
-
- protected virtual IType CreateConcreteCallableType(Node sourceNode, AnonymousCallableType anonymousType)
- {
- Module module = GetCompilerGeneratedTypesModule();
-
- string name = string.Format("___callable{0}", module.Members.Count);
- ClassDefinition cd = CreateCallableDefinition(name);
- cd.Modifiers |= TypeMemberModifiers.Public;
- cd.LexicalInfo = sourceNode.LexicalInfo;
-
- cd.Members.Add(CreateInvokeMethod(anonymousType));
-
- Method beginInvoke = CreateBeginInvokeMethod(anonymousType);
- cd.Members.Add(beginInvoke);
-
- cd.Members.Add(CreateEndInvokeMethod(anonymousType));
- _compilerGeneratedTypesModule.Members.Add(cd);
-
- CreateCallableTypeBeginInvokeExtensions(anonymousType, beginInvoke);
-
- return (IType)cd.Entity;
- }
-
- private void CreateCallableTypeBeginInvokeExtensions(AnonymousCallableType anonymousType, Method beginInvoke)
- {
- ClassDefinition extensions = GetCompilerGeneratedExtensionsClass();
- extensions.Members.Add(CreateBeginInvokeCallbackOnlyExtension(anonymousType, beginInvoke));
- extensions.Members.Add(CreateBeginInvokeSimplerExtension(anonymousType, beginInvoke));
- }
-
- private static void InvalidNode(Node node)
- {
- throw CompilerErrorFactory.InvalidNode(node);
- }
-
- public class DuckTypeImpl : ExternalType
- {
- public DuckTypeImpl(TypeSystemServices typeSystemServices) :
- base(typeSystemServices, Types.Object)
- {
- }
- }
-
- #region VoidTypeImpl
- class VoidTypeImpl : ExternalType
- {
- internal VoidTypeImpl(TypeSystemServices typeSystemServices) : base(typeSystemServices, Types.Void)
- {
- }
-
- override public bool Resolve(List targetList, string name, EntityType flags)
- {
- return false;
- }
-
- override public bool IsSubclassOf(IType other)
- {
- return false;
- }
-
- override public bool IsAssignableFrom(IType other)
- {
- return false;
- }
- }
-
- #endregion
- }
-}
+ }
+
+ bool IsCallableType(IType type)
+ {
+ return (ICallableType.IsAssignableFrom(type)) ||
+ (type is ICallableType);
+ }
+
+ public AnonymousCallableType GetCallableType(IMethod method)
+ {
+ CallableSignature signature = new CallableSignature(method);
+ return GetCallableType(signature);
+ }
+
+ public AnonymousCallableType GetCallableType(CallableSignature signature)
+ {
+ AnonymousCallableType type = (AnonymousCallableType)_anonymousCallableTypes[signature];
+ if (null == type)
+ {
+ type = new AnonymousCallableType(this, signature);
+ _anonymousCallableTypes.Add(signature, type);
+ }
+ return type;
+ }
+
+ public IType GetConcreteCallableType(Node sourceNode, CallableSignature signature)
+ {
+ AnonymousCallableType type = GetCallableType(signature);
+ return GetConcreteCallableType(sourceNode, type);
+ }
+
+ public IType GetEnumeratorItemType(IType iteratorType)
+ {
+ if (iteratorType.IsArray) return ((IArrayType)iteratorType).GetElementType();
+ if (StringType == iteratorType) return CharType;
+
+ if (iteratorType.IsClass)
+ {
+ IType enumeratorItemType = GetEnumeratorItemTypeFromAttribute(iteratorType);
+ if (null != enumeratorItemType)
+ {
+ return enumeratorItemType;
+ }
+ }
+#if NET_2_0
+ IType genericItemType = GetEnumeratorItemTypeFromGenericEnumerable(iteratorType);
+ if (null != genericItemType)
+ {
+ return genericItemType;
+ }
+#endif
+ return ObjectType;
+ }
+
+ public IType GetExpressionType(Expression node)
+ {
+ IType type = node.ExpressionType;
+ if (null == type)
+ {
+ throw CompilerErrorFactory.InvalidNode(node);
+ }
+ return type;
+ }
+
+ public IType GetConcreteExpressionType(Expression expression)
+ {
+ IType type = GetExpressionType(expression);
+ AnonymousCallableType anonymousType = type as AnonymousCallableType;
+ if (null != anonymousType)
+ {
+ IType concreteType = GetConcreteCallableType(expression, anonymousType);
+ expression.ExpressionType = concreteType;
+ return concreteType;
+ }
+ return type;
+ }
+
+ public void MapToConcreteExpressionTypes(ExpressionCollection items)
+ {
+ foreach (Expression item in items)
+ {
+ GetConcreteExpressionType(item);
+ }
+ }
+
+ public ClassDefinition GetCompilerGeneratedExtensionsClass()
+ {
+ if (null == _compilerGeneratedExtensionsClass)
+ {
+ BooClassBuilder builder = CodeBuilder.CreateClass("CompilerGeneratedExtensions");
+ builder.Modifiers = TypeMemberModifiers.Final|TypeMemberModifiers.Transient|TypeMemberModifiers.Public;
+ builder.AddBaseType(ObjectType);
+
+ BooMethodBuilder ctor = builder.AddConstructor();
+ ctor.Modifiers = TypeMemberModifiers.Private;
+ ctor.Body.Add(
+ CodeBuilder.CreateSuperConstructorInvocation(ObjectType));
+
+ ClassDefinition cd = builder.ClassDefinition;
+ Module module = GetCompilerGeneratedExtensionsModule();
+ module.Members.Add(cd);
+ ((ModuleEntity)module.Entity).InitializeModuleClass(cd);
+
+ _compilerGeneratedExtensionsClass = cd;
+ }
+ return _compilerGeneratedExtensionsClass;
+ }
+
+ public Module GetCompilerGeneratedExtensionsModule()
+ {
+ if (null == _compilerGeneratedExtensionsModule)
+ {
+ _compilerGeneratedExtensionsModule = NewModule(null);
+ }
+ return _compilerGeneratedExtensionsModule;
+ }
+
+ public void AddCompilerGeneratedType(TypeDefinition type)
+ {
+ GetCompilerGeneratedTypesModule().Members.Add(type);
+ }
+
+ public Module GetCompilerGeneratedTypesModule()
+ {
+ if (null == _compilerGeneratedTypesModule)
+ {
+ _compilerGeneratedTypesModule = NewModule("CompilerGenerated");
+ }
+ return _compilerGeneratedTypesModule;
+ }
+
+ private Module NewModule(string ns)
+ {
+ Module module = new Module();
+ if (null != ns) module.Namespace = new NamespaceDeclaration(ns);
+ module.Entity = new ModuleEntity(_context.NameResolutionService, this, module);
+ _context.CompileUnit.Modules.Add(module);
+ return module;
+ }
+
+ public ClassDefinition CreateCallableDefinition(string name)
+ {
+ ClassDefinition cd = new ClassDefinition();
+ cd.BaseTypes.Add(CodeBuilder.CreateTypeReference(this.MulticastDelegateType));
+ cd.BaseTypes.Add(CodeBuilder.CreateTypeReference(this.ICallableType));
+ cd.Name = name;
+ cd.Modifiers = TypeMemberModifiers.Final;
+ cd.Members.Add(CreateCallableConstructor());
+ cd.Members.Add(CreateCallMethod());
+ cd.Entity = new InternalCallableType(this, cd);
+ return cd;
+ }
+
+ Method CreateCallMethod()
+ {
+ Method method = new Method("Call");
+ method.Modifiers = TypeMemberModifiers.Public|TypeMemberModifiers.Virtual;
+ method.Parameters.Add(CodeBuilder.CreateParameterDeclaration(1, "args", ObjectArrayType));
+ method.ReturnType = CodeBuilder.CreateTypeReference(ObjectType);
+ method.Entity = new InternalMethod(this, method);
+ return method;
+ }
+
+ Constructor CreateCallableConstructor()
+ {
+ Constructor constructor = new Constructor();
+ constructor.Modifiers = TypeMemberModifiers.Public;
+ constructor.ImplementationFlags = MethodImplementationFlags.Runtime;
+ constructor.Parameters.Add(
+ CodeBuilder.CreateParameterDeclaration(1, "instance", ObjectType));
+ constructor.Parameters.Add(
+ CodeBuilder.CreateParameterDeclaration(2, "method", IntPtrType));
+ constructor.Entity = new InternalConstructor(this, constructor);
+ return constructor;
+ }
+
+ public bool AreTypesRelated(IType lhs, IType rhs)
+ {
+ ICallableType ctype = lhs as ICallableType;
+ if (null != ctype)
+ {
+ return ctype.IsAssignableFrom(rhs)
+ || ctype.IsSubclassOf(rhs);
+ }
+
+ return lhs.IsAssignableFrom(rhs)
+ || (lhs.IsInterface && !rhs.IsFinal)
+ || (rhs.IsInterface && !lhs.IsFinal)
+ || CanBeReachedByDownCastOrPromotion(lhs, rhs)
+ || FindImplicitConversionOperator(rhs,lhs) != null;
+ }
+
+ public IMethod FindExplicitConversionOperator(IType fromType, IType toType)
+ {
+ return FindConversionOperator("op_Explicit", fromType, toType);
+ }
+
+ public IMethod FindImplicitConversionOperator(IType fromType, IType toType)
+ {
+ return FindConversionOperator("op_Implicit", fromType, toType);
+ }
+
+ public IMethod FindConversionOperator(string name, IType fromType, IType toType)
+ {
+ while (fromType != this.ObjectType)
+ {
+ IMethod method = FindConversionOperator(name, fromType, toType, fromType.GetMembers());
+ if (null != method) return method;
+ method = FindConversionOperator(name, fromType, toType, toType.GetMembers());
+ if (null != method) return method;
+ method = FindConversionOperator(name, fromType, toType, FindExtension(fromType, name));
+ if (null != method) return method;
+
+ fromType = fromType.BaseType;
+ if (null == fromType) break;
+ }
+ return null;
+ }
+
+ private IEntity[] FindExtension(IType fromType, string name)
+ {
+ IEntity extension = _context.NameResolutionService.ResolveExtension(fromType, name);
+ if (null == extension) return Ambiguous.NoEntities;
+
+ Ambiguous a = extension as Ambiguous;
+ if (null != a) return a.Entities;
+ return new IEntity[] { extension };
+ }
+
+ IMethod FindConversionOperator(string name, IType fromType, IType toType, IEntity[] candidates)
+ {
+ foreach (IEntity entity in candidates)
+ {
+ if (EntityType.Method != entity.EntityType || name != entity.Name) continue;
+ IMethod method = (IMethod)entity;
+ if (IsConversionOperator(method, fromType, toType)) return method;
+ }
+ return null;
+ }
+
+ bool IsConversionOperator(IMethod method, IType fromType, IType toType)
+ {
+ if (!method.IsStatic) return false;
+ if (method.ReturnType != toType) return false;
+ IParameter[] parameters = method.GetParameters();
+ return (1 == parameters.Length && fromType == parameters[0].Type);
+ }
+
+ public bool IsCallableTypeAssignableFrom(ICallableType lhs, IType rhs)
+ {
+ if (lhs == rhs || Null.Default == rhs)
+ {
+ return true;
+ }
+
+ ICallableType other = rhs as ICallableType;
+ if (null != other)
+ {
+ CallableSignature lvalue = lhs.GetSignature();
+ CallableSignature rvalue = other.GetSignature();
+ if (lvalue == rvalue)
+ {
+ return true;
+ }
+
+ IParameter[] lparams = lvalue.Parameters;
+ IParameter[] rparams = rvalue.Parameters;
+ if (lparams.Length >= rparams.Length)
+ {
+ for (int i=0; i 1)
+ {
+ IEntity[] tags = new IEntity[info.Length];
+ for (int i=0; i 0)
+ {
+ return Map(info[0]);
+ }
+ return null;
+ }
+
+ public IEntity Map(MemberInfo mi)
+ {
+ IEntity tag = (IEntity)_entityCache[GetCacheKey(mi)];
+ if (null == tag)
+ {
+ switch (mi.MemberType)
+ {
+ case MemberTypes.Method:
+ {
+ return Map((MethodInfo)mi);
+ }
+
+ case MemberTypes.Constructor:
+ {
+ return Map((ConstructorInfo)mi);
+ }
+
+ case MemberTypes.Field:
+ {
+ tag = new ExternalField(this, (FieldInfo)mi);
+ break;
+ }
+
+ case MemberTypes.Property:
+ {
+ tag = new ExternalProperty(this, (PropertyInfo)mi);
+ break;
+ }
+
+ case MemberTypes.Event:
+ {
+ tag = new ExternalEvent(this, (EventInfo)mi);
+ break;
+ }
+
+ case MemberTypes.NestedType:
+ {
+ return Map((Type)mi);
+ }
+
+ default:
+ {
+ throw new NotImplementedException(mi.ToString());
+ }
+ }
+ _entityCache.Add(GetCacheKey(mi), tag);
+ }
+ return tag;
+ }
+
+ public string GetSignature(IEntityWithParameters method)
+ {
+ return GetSignature(method, true);
+ }
+
+ public string GetSignature(IEntityWithParameters method, bool includeFullName)
+ {
+ _buffer.Length = 0;
+ if (includeFullName)
+ {
+ _buffer.Append(method.FullName);
+ }
+ else
+ {
+ _buffer.Append(method.Name);
+ }
+ _buffer.Append("(");
+
+ IParameter[] parameters = method.GetParameters();
+ for (int i=0; i 0) { _buffer.Append(", "); }
+ if (method.AcceptVarArgs && i == parameters.Length-1) { _buffer.Append('*'); }
+ _buffer.Append(parameters[i].Type);
+ }
+ _buffer.Append(")");
+ return _buffer.ToString();
+ }
+
+ public object GetCacheKey(MemberInfo mi)
+ {
+ return mi;
+ }
+
+ public IEntity ResolvePrimitive(string name)
+ {
+ return (IEntity)_primitives[name];
+ }
+
+ public bool IsPrimitive(string name)
+ {
+ return _primitives.ContainsKey(name);
+ }
+
+ ///
+ /// checks if the passed type will be equivalente to
+ /// System.Object in runtime (accounting for the presence
+ /// of duck typing).
+ ///
+ public bool IsSystemObject(IType type)
+ {
+ return type == ObjectType || type == DuckType;
+ }
+
+ protected virtual void PreparePrimitives()
+ {
+ AddPrimitiveType("duck", DuckType);
+ AddPrimitiveType("void", VoidType);
+ AddPrimitiveType("bool", BoolType);
+ AddPrimitiveType("char", CharType);
+ AddPrimitiveType("date", DateTimeType);
+ AddPrimitiveType("timespan", TimeSpanType);
+ AddPrimitiveType("string", StringType);
+ AddPrimitiveType("object", ObjectType);
+ AddPrimitiveType("regex", RegexType);
+ AddPrimitiveType("sbyte", SByteType);
+ AddPrimitiveType("byte", ByteType);
+ AddPrimitiveType("short", ShortType);
+ AddPrimitiveType("ushort", UShortType);
+ AddPrimitiveType("int", IntType);
+ AddPrimitiveType("uint", UIntType);
+ AddPrimitiveType("long", LongType);
+ AddPrimitiveType("ulong", ULongType);
+ AddPrimitiveType("single", SingleType);
+ AddPrimitiveType("double", DoubleType);
+ AddPrimitiveType("decimal", DecimalType);
+ AddPrimitiveType("callable", ICallableType);
+ }
+
+ protected virtual void PrepareBuiltinFunctions()
+ {
+ AddBuiltin(BuiltinFunction.Len);
+ AddBuiltin(BuiltinFunction.AddressOf);
+ AddBuiltin(BuiltinFunction.Eval);
+ AddBuiltin(BuiltinFunction.Switch);
+ }
+
+ protected void AddPrimitiveType(string name, ExternalType type)
+ {
+ _primitives[name] = type;
+ type.PrimitiveName = name;
+ }
+
+ protected void AddBuiltin(BuiltinFunction function)
+ {
+ _primitives[function.Name] = function;
+ }
+
+ void Cache(ExternalType tag)
+ {
+ _entityCache[tag.ActualType] = tag;
+ }
+
+ void Cache(object key, IType tag)
+ {
+ _entityCache[key] = tag;
+ }
+
+ Method CreateBeginInvokeMethod(ICallableType anonymousType)
+ {
+ Method method = CodeBuilder.CreateRuntimeMethod("BeginInvoke", Map(typeof(IAsyncResult)),
+ anonymousType.GetSignature().Parameters, false);
+
+ int delta=method.Parameters.Count;
+ method.Parameters.Add(
+ CodeBuilder.CreateParameterDeclaration(delta+1, "callback", Map(typeof(AsyncCallback))));
+ method.Parameters.Add(
+ CodeBuilder.CreateParameterDeclaration(delta+1, "asyncState", ObjectType));
+ return method;
+ }
+
+ Method CreateBeginInvokeExtension(ICallableType anonymousType, Method beginInvoke, out MethodInvocationExpression mie)
+ {
+ InternalMethod beginInvokeEntity = (InternalMethod)beginInvoke.Entity;
+
+ Method extension = CodeBuilder.CreateMethod("BeginInvoke", Map(typeof(IAsyncResult)),
+ TypeMemberModifiers.Public|TypeMemberModifiers.Static);
+ extension.Attributes.Add(CodeBuilder.CreateAttribute(Types.ExtensionAttribute));
+
+ ParameterDeclaration self = CodeBuilder.CreateParameterDeclaration(0, "self", beginInvokeEntity.DeclaringType);
+
+ extension.Parameters.Add(self);
+ CodeBuilder.DeclareParameters(extension, 1, anonymousType.GetSignature().Parameters);
+
+ mie = CodeBuilder.CreateMethodInvocation(
+ CodeBuilder.CreateReference(self),
+ beginInvokeEntity);
+
+ ParameterDeclarationCollection parameters = extension.Parameters;
+ for (int i=1; i));
+
+ IType itemType = null;
+ foreach (IType type in FindConstructedTypes(iteratorType, genericEnumerable))
+ {
+ IType candidateItemType = type.GenericTypeInfo.GenericArguments[0];
+ _context.TraceVerbose("Candidate enumerable item type for {0}: {1}",
+ iteratorType, candidateItemType);
+
+ if (itemType != null)
+ {
+ itemType = GetMostGenericType(itemType, candidateItemType);
+ }
+ else
+ {
+ itemType = candidateItemType;
+ }
+ }
+
+ return itemType;
+ }
+
+ System.Collections.Generic.IEnumerable FindConstructedTypes(IType type, IType definition)
+ {
+ while (type != null)
+ {
+ string typeName = (type is ExternalType ? ((ExternalType)type).ActualType.Name : type.Name);
+
+ if (type.GenericTypeInfo != null &&
+ type.GenericTypeInfo.FullyConstructed &&
+ type.GenericTypeInfo.GenericDefinition == definition)
+ {
+ yield return type;
+ }
+
+ foreach (IType interfaceType in type.GetInterfaces())
+ {
+ foreach (IType match in FindConstructedTypes(interfaceType, definition))
+ {
+ yield return match;
+ }
+ }
+
+ type = type.BaseType;
+ }
+ }
+#endif
+
+ public virtual IType GetConcreteCallableType(Node sourceNode, AnonymousCallableType anonymousType)
+ {
+ if (null == anonymousType.ConcreteType)
+ {
+ anonymousType.ConcreteType = CreateConcreteCallableType(sourceNode, anonymousType);
+ }
+ return anonymousType.ConcreteType;
+ }
+
+ protected virtual IType CreateConcreteCallableType(Node sourceNode, AnonymousCallableType anonymousType)
+ {
+ Module module = GetCompilerGeneratedTypesModule();
+
+ string name = string.Format("___callable{0}", module.Members.Count);
+ ClassDefinition cd = CreateCallableDefinition(name);
+ cd.Modifiers |= TypeMemberModifiers.Public;
+ cd.LexicalInfo = sourceNode.LexicalInfo;
+
+ cd.Members.Add(CreateInvokeMethod(anonymousType));
+
+ Method beginInvoke = CreateBeginInvokeMethod(anonymousType);
+ cd.Members.Add(beginInvoke);
+
+ cd.Members.Add(CreateEndInvokeMethod(anonymousType));
+ _compilerGeneratedTypesModule.Members.Add(cd);
+
+ CreateCallableTypeBeginInvokeExtensions(anonymousType, beginInvoke);
+
+ return (IType)cd.Entity;
+ }
+
+ private void CreateCallableTypeBeginInvokeExtensions(AnonymousCallableType anonymousType, Method beginInvoke)
+ {
+ ClassDefinition extensions = GetCompilerGeneratedExtensionsClass();
+ extensions.Members.Add(CreateBeginInvokeCallbackOnlyExtension(anonymousType, beginInvoke));
+ extensions.Members.Add(CreateBeginInvokeSimplerExtension(anonymousType, beginInvoke));
+ }
+
+ private static void InvalidNode(Node node)
+ {
+ throw CompilerErrorFactory.InvalidNode(node);
+ }
+
+ public class DuckTypeImpl : ExternalType
+ {
+ public DuckTypeImpl(TypeSystemServices typeSystemServices) :
+ base(typeSystemServices, Types.Object)
+ {
+ }
+ }
+
+ #region VoidTypeImpl
+ class VoidTypeImpl : ExternalType
+ {
+ internal VoidTypeImpl(TypeSystemServices typeSystemServices) : base(typeSystemServices, Types.Void)
+ {
+ }
+
+ override public bool Resolve(List targetList, string name, EntityType flags)
+ {
+ return false;
+ }
+
+ override public bool IsSubclassOf(IType other)
+ {
+ return false;
+ }
+
+ override public bool IsAssignableFrom(IType other)
+ {
+ return false;
+ }
+ }
+
+ #endregion
+ }
+}
Index: src/Boo.Lang/Boo.Lang.csproj
===================================================================
--- src/Boo.Lang/Boo.Lang.csproj (revision 2352)
+++ src/Boo.Lang/Boo.Lang.csproj (working copy)
@@ -49,7 +49,6 @@
-
Index: src/Boo.sln
===================================================================
--- src/Boo.sln (revision 2352)
+++ src/Boo.sln (working copy)
@@ -1,6 +1,5 @@
-
-Microsoft Visual Studio Solution File, Format Version 9.00
-# Visual Studio 2005
+Microsoft Visual Studio Solution File, Format Version 9.00
+# SharpDevelop 2.1.0.1825
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Boo.Lang", "Boo.Lang\Boo.Lang.csproj", "{8F36FEA8-5EC9-46D3-BE8D-39AE484C1266}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Boo.Lang.Parser", "Boo.Lang.Parser\Boo.Lang.Parser.csproj", "{C1943936-DBBD-4331-94C3-BE4F7E6229DA}"
@@ -31,6 +30,10 @@
{3D5461D4-F243-41A5-927B-6636CEE2E6B8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3D5461D4-F243-41A5-927B-6636CEE2E6B8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3D5461D4-F243-41A5-927B-6636CEE2E6B8}.Release|Any CPU.Build.0 = Release|Any CPU
+ {86284E52-4C54-48CB-A286-4E34047AF1EF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {86284E52-4C54-48CB-A286-4E34047AF1EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {86284E52-4C54-48CB-A286-4E34047AF1EF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {86284E52-4C54-48CB-A286-4E34047AF1EF}.Release|Any CPU.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Index: tests/testcases/net2/generics/callable-1.boo
===================================================================
--- tests/testcases/net2/generics/callable-1.boo (revision 0)
+++ tests/testcases/net2/generics/callable-1.boo (revision 0)
@@ -0,0 +1,14 @@
+"""
+42
+"""
+
+import System
+import System.Threading
+import System.Collections.Generic
+
+f as Action of int
+f = {i as int | print i * 2}
+
+l = List of int()
+l.Add(21)
+l.ForEach(f)
Index: tests/testcases/net2/generics/callable-2.boo
===================================================================
--- tests/testcases/net2/generics/callable-2.boo (revision 0)
+++ tests/testcases/net2/generics/callable-2.boo (revision 0)
@@ -0,0 +1,18 @@
+"""
+Avish
+"""
+
+import System
+import System.Collections.Generic
+
+public class Person:
+ public Name as string
+ public def constructor(name as string):
+ Name = name
+
+f as Action of Person
+f = {p as Person | print p.Name}
+
+l = List of Person()
+l.Add(Person("Avish"))
+l.ForEach(f)
Index: tests/testcases/net2/generics/collections-2.boo
===================================================================
--- tests/testcases/net2/generics/collections-2.boo (revision 0)
+++ tests/testcases/net2/generics/collections-2.boo (revision 0)
@@ -0,0 +1,14 @@
+"""
+Avish
+"""
+
+import System.Collections.Generic
+
+class Person:
+ public Name as string
+
+l = List of Person()
+p = Person()
+p.Name = "Avish"
+l.Add(p)
+print l[0].Name
Index: tests/testcases/net2/generics/generators-1.boo
===================================================================
--- tests/testcases/net2/generics/generators-1.boo (revision 0)
+++ tests/testcases/net2/generics/generators-1.boo (revision 0)
@@ -0,0 +1,14 @@
+"""
+1
+2
+3
+"""
+
+import System.Collections.Generic
+
+public def YieldInts() as IEnumerable of int:
+ yield 1
+ yield 2
+ yield 3
+
+for i in YieldInts(): print i
Index: tests/testcases/net2/generics/interface-1.boo
===================================================================
--- tests/testcases/net2/generics/interface-1.boo (revision 0)
+++ tests/testcases/net2/generics/interface-1.boo (revision 0)
@@ -0,0 +1,22 @@
+"""
+-1
+"""
+
+import System
+import System.Collections.Generic
+
+public class Person:
+ public Name as string
+
+ public def constructor(name as string):
+ Name = name
+
+public class PersonComparer(IComparer of Person):
+ public def Compare(x as Person, y as Person):
+ return string.Compare(x.Name, y.Name)
+
+p1 = Person("Avish")
+p2 = Person("Bet's On!")
+c = PersonComparer() as IComparer of Person
+print c.Compare(p1, p2)
+
Index: tests/testcases/net2/generics/mixed-1.boo
===================================================================
--- tests/testcases/net2/generics/mixed-1.boo (revision 0)
+++ tests/testcases/net2/generics/mixed-1.boo (revision 0)
@@ -0,0 +1,23 @@
+"""
+Thingy
+"""
+
+import System.Collections.Generic
+
+class Thingy:
+ _thingies = List of Thingy()
+
+ public AsList as List of Thingy:
+ get: return _thingies
+
+ public AsIList as IList of Thingy:
+ get: return _thingies
+
+ public AsICollection as ICollection of Thingy:
+ get: return _thingies
+
+ public AsNonGeneric as System.Collections.ICollection:
+ get: return _thingies
+
+t = Thingy()
+print t
Index: tests/testcases/net2/generics/mixed-2.boo
===================================================================
--- tests/testcases/net2/generics/mixed-2.boo (revision 0)
+++ tests/testcases/net2/generics/mixed-2.boo (revision 0)
@@ -0,0 +1,23 @@
+"""
+Avish
+Avish
+Avish
+"""
+
+import System.Collections.Generic
+
+class Person:
+ public Name as string
+
+ public def constructor(name as string):
+ Name = name
+
+def MatchName(name as string):
+ return {p as Person | p.Name == name}
+
+l = List of Person()
+l.Add(Person("Avish"))
+
+print l[0].Name
+print l.Find(MatchName("Avish")).Name
+print l.Find({p as Person | p.Name == "Avish"}).Name
Index: tests/testcases/net2/generics/override-1.boo
===================================================================
--- tests/testcases/net2/generics/override-1.boo (revision 0)
+++ tests/testcases/net2/generics/override-1.boo (revision 0)
@@ -0,0 +1,19 @@
+"""
+Avish added!
+"""
+
+import System.Collections.ObjectModel
+
+public class Person:
+ public Name as string
+
+ public def constructor(name as string):
+ Name = name
+
+public class PersonList(Collection of Person):
+ public override def InsertItem(index as int, p as Person):
+ print "${p.Name} added!"
+ super.InsertItem(index, p)
+
+pl = PersonList()
+pl.Add(Person("Avish"))