/src/Boo.Lang.Compiler/Steps/ProcessMethodBodies.cs
C# | 5994 lines | 5017 code | 851 blank | 126 comment | 1047 complexity | c81e3259365c03049891a150beb9d223 MD5 | raw file
Possible License(s): GPL-2.0
Large files files are truncated, but you can click here to view the full file
- #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.Collections.Generic;
- using System.Diagnostics;
- using System.IO;
- using System.Linq;
- using System.Reflection;
- using System.Text;
- using Boo.Lang.Compiler.Ast;
- using Boo.Lang.Compiler.Ast.Visitors;
- using Boo.Lang.Compiler.Steps.Generators;
- using Boo.Lang.Compiler.TypeSystem;
- using Boo.Lang.Compiler.TypeSystem.Core;
- using Boo.Lang.Compiler.TypeSystem.Generics;
- using Boo.Lang.Compiler.TypeSystem.Internal;
- using Boo.Lang.Compiler.TypeSystem.Reflection;
- using Boo.Lang.Compiler.TypeSystem.Services;
- using Boo.Lang.Environments;
- using Boo.Lang.Runtime;
- using Attribute = Boo.Lang.Compiler.Ast.Attribute;
- using Module = Boo.Lang.Compiler.Ast.Module;
-
- namespace Boo.Lang.Compiler.Steps
- {
- /// <summary>
- /// AST semantic evaluation.
- /// </summary>
- public class ProcessMethodBodies : AbstractNamespaceSensitiveVisitorCompilerStep, ITypeMemberReifier
- {
- static readonly ExpressionCollection EmptyExpressionCollection = new ExpressionCollection();
-
- static readonly object OptionalReturnStatementAnnotation = new object();
-
- static readonly object ResolvedAsExtensionAnnotation = new object();
-
- private Stack<InternalMethod> _methodStack;
-
- private Stack _memberStack;
- // for accurate error reporting during type inference
-
- private Module _currentModule;
-
- private InternalMethod _currentMethod;
-
- private bool _optimizeNullComparisons = true;
-
- const string TempInitializerName = "$___temp_initializer";
-
- public override void Initialize(CompilerContext context)
- {
- base.Initialize(context);
-
- _currentModule = null;
- _currentMethod = null;
- _methodStack = new Stack<InternalMethod>();
- _memberStack = new Stack();
- _callableResolutionService = new EnvironmentProvision<CallableResolutionService>();
- _invocationTypeReferenceRules = new EnvironmentProvision<InvocationTypeInferenceRules>();
- _typeChecker = new EnvironmentProvision<TypeChecker>();
- _methodCache = new EnvironmentProvision<RuntimeMethodCache>();
- }
-
- override public void Run()
- {
- NameResolutionService.Reset();
- Visit(CompileUnit);
- }
-
- override public void Dispose()
- {
- base.Dispose();
-
- _currentModule = null;
- _currentMethod = null;
- _methodStack = null;
- _memberStack = null;
- }
-
- protected CallableResolutionService CallableResolutionService
- {
- get { return _callableResolutionService; }
- }
-
- private EnvironmentProvision<CallableResolutionService> _callableResolutionService;
-
- protected IMethod ResolveMethod(IType type, string name)
- {
- return NameResolutionService.ResolveMethod(type, name);
- }
-
- protected IProperty ResolveProperty(IType type, string name)
- {
- return NameResolutionService.ResolveProperty(type, name);
- }
-
- override public void OnModule(Module module)
- {
- if (WasVisited(module))
- return;
- MarkVisited(module);
-
- _currentModule = module;
-
- EnterNamespace(InternalModule.ScopeFor(module));
-
- Visit(module.Members);
- Visit(module.AssemblyAttributes);
-
- LeaveNamespace();
- }
-
- override public void OnInterfaceDefinition(InterfaceDefinition node)
- {
- if (WasVisited(node)) return;
- MarkVisited(node);
-
- VisitTypeDefinition(node);
- }
-
- private void VisitBaseTypes(TypeDefinition node)
- {
- foreach (var baseTypeRef in node.BaseTypes)
- EnsureRelatedNodeWasVisited(baseTypeRef, baseTypeRef.Entity);
- }
-
- private void VisitTypeDefinition(TypeDefinition node)
- {
- var ns = (INamespace)GetEntity(node);
- EnterNamespace(ns);
- VisitBaseTypes(node);
- Visit(node.Attributes);
- Visit(node.Members);
- LeaveNamespace();
- }
-
- override public void OnClassDefinition(ClassDefinition node)
- {
- if (WasVisited(node))
- return;
- MarkVisited(node);
-
- VisitTypeDefinition(node);
- FlushFieldInitializers(node);
- }
-
- void FlushFieldInitializers(ClassDefinition node)
- {
- foreach (TypeMember member in node.Members.ToArray())
- {
- switch (member.NodeType)
- {
- case NodeType.Field:
- ProcessFieldInitializer((Field) member);
- break;
- case NodeType.StatementTypeMember:
- ProcessStatementTypeMemberInitializer(node, ((StatementTypeMember)member));
- break;
- }
- }
-
- var initializer = (Method) node["$initializer$"];
- if (null != initializer)
- {
- AddInitializerToInstanceConstructors(node, initializer);
- node.Members.Remove(initializer);
- }
- }
-
- private void ProcessStatementTypeMemberInitializer(ClassDefinition node, StatementTypeMember statementTypeMember)
- {
- var stmt = statementTypeMember.Statement;
-
- var initializer = GetInitializerFor(node, node.IsStatic);
- initializer.Body.Add(stmt);
-
- var entity = (InternalMethod) GetEntity(initializer);
- ProcessNodeInMethodContext(entity, entity, stmt);
-
- node.Members.Remove(statementTypeMember);
- }
-
- override public void OnAttribute(Attribute node)
- {
- var tag = node.Entity as IType;
- if (null != tag && !IsError(tag))
- {
- Visit(node.Arguments);
- ResolveNamedArguments(tag, node.NamedArguments);
-
- IConstructor constructor = GetCorrectConstructor(node, tag, node.Arguments);
- if (null != constructor)
- {
- Bind(node, constructor);
- }
- }
- }
-
- private static bool IsError(IEntity entity)
- {
- return TypeSystemServices.IsError(entity);
- }
-
- override public void OnProperty(Property node)
- {
- if (WasVisited(node))
- return;
- MarkVisited(node);
-
- Visit(node.Attributes);
- Visit(node.Type);
- Visit(node.Parameters);
-
- ResolvePropertyOverride(node);
-
- ProcessGetter(node);
-
- if (node.Type == null)
- node.Type = CodeBuilder.CreateTypeReference(node.LexicalInfo, InferTypeOfProperty(node));
-
- if (node.Getter != null)
- node.Getter.ReturnType = node.Type.CloneNode();
-
- ProcessSetter(node);
- }
-
- private void ProcessSetter(Property node)
- {
- if (node.Setter != null)
- {
- NormalizeSetterOf(node);
- Visit(node.Setter);
- }
- }
-
- private void ProcessGetter(Property node)
- {
- if (node.Getter != null)
- {
- NormalizeGetterOf(node);
- Visit(node.Getter);
- }
- }
-
- private static void NormalizeGetterOf(Property node)
- {
- node.Getter.Parameters.ExtendWithClones(node.Parameters);
- if (node.Getter.ReturnType == null && node.Type != null)
- node.Getter.ReturnType = node.Type.CloneNode();
- }
-
- private IType InferTypeOfProperty(Property node)
- {
- if (node.Getter == null)
- return TypeSystemServices.ObjectType;
-
- var getterType = GetEntity(node.Getter).ReturnType;
- if (getterType != TypeSystemServices.VoidType)
- return getterType;
-
- return TypeSystemServices.ObjectType;
- }
-
- private void NormalizeSetterOf(Property node)
- {
- var setter = node.Setter;
- setter.Name = "set_" + node.Name;
-
- var setterParameters = setter.Parameters;
- setterParameters.ExtendWithClones(node.Parameters);
- setterParameters.Add(CodeBuilder.CreateParameterDeclaration(CodeBuilder.GetFirstParameterIndex(setter) + setterParameters.Count, "value", GetType(node.Type)));
- }
-
- override public void OnStatementTypeMember(StatementTypeMember node)
- {
- // statement type members are later
- // processed as initializers
- }
-
- override public void OnField(Field node)
- {
- if (WasVisited(node))
- return;
- MarkVisited(node);
-
- var entity = (InternalField)GetEntity(node);
-
- Visit(node.Attributes);
- Visit(node.Type);
-
- if (node.Initializer != null)
- {
- var type = (null != node.Type) ? GetType(node.Type) : null;
- if (null != type && TypeSystemServices.IsNullable(type))
- BindNullableInitializer(node, node.Initializer, type);
-
- if (entity.DeclaringType.IsValueType && !node.IsStatic)
- Error(CompilerErrorFactory.ValueTypeFieldsCannotHaveInitializers(node.Initializer));
-
- try
- {
- PushMember(node);
- PreProcessFieldInitializer(node);
- }
- finally
- {
- PopMember();
- }
- }
- else
- {
- if (null == node.Type)
- {
- node.Type = CreateTypeReference(node.LexicalInfo, TypeSystemServices.ObjectType);
- }
- }
- CheckFieldType(node.Type);
- }
-
- static bool IsValidLiteralInitializer(Expression e)
- {
- switch (e.NodeType)
- {
- case NodeType.BoolLiteralExpression:
- case NodeType.IntegerLiteralExpression:
- case NodeType.DoubleLiteralExpression:
- case NodeType.NullLiteralExpression:
- case NodeType.StringLiteralExpression:
- return true;
- }
- return false;
- }
-
- void ProcessLiteralField(Field node)
- {
- Visit(node.Initializer);
- ProcessFieldInitializerType(node, node.Initializer.ExpressionType);
- ((InternalField)node.Entity).StaticValue = node.Initializer;
- node.Initializer = null;
- }
-
- void ProcessFieldInitializerType(Field node, IType initializerType)
- {
- if (null == node.Type)
- node.Type = CreateTypeReference(node.LexicalInfo, MapWildcardType(initializerType));
- else
- AssertTypeCompatibility(node.Initializer, GetType(node.Type), initializerType);
- }
-
- private TypeReference CreateTypeReference(LexicalInfo info, IType type)
- {
- var reference = CodeBuilder.CreateTypeReference(type);
- reference.LexicalInfo = info;
- return reference;
- }
-
- private void PreProcessFieldInitializer(Field node)
- {
- Expression initializer = node.Initializer;
- if (node.IsFinal && node.IsStatic)
- {
- if (IsValidLiteralInitializer(initializer))
- {
- ProcessLiteralField(node);
- return;
- }
- }
-
- BlockExpression closure = node.Initializer as BlockExpression;
- if (closure != null)
- {
- InferClosureSignature(closure);
- }
-
- Method method = GetInitializerMethod(node);
- InternalMethod entity = (InternalMethod)method.Entity;
-
- ReferenceExpression temp = new ReferenceExpression(TempInitializerName);
-
- BinaryExpression assignment = new BinaryExpression(
- node.LexicalInfo,
- BinaryOperatorType.Assign,
- temp,
- initializer);
-
- ProcessNodeInMethodContext(entity, entity, assignment);
- method.Locals.RemoveByEntity(temp.Entity);
-
- IType initializerType = GetExpressionType(assignment.Right);
- ProcessFieldInitializerType(node, initializerType);
- node.Initializer = assignment.Right;
- }
-
- void ProcessFieldInitializer(Field node)
- {
- Expression initializer = node.Initializer;
- if (null == initializer) return;
-
- //do not unnecessarily assign fields to default values
- switch (initializer.NodeType)
- {
- case NodeType.NullLiteralExpression:
- node.Initializer = null;
- return;
- case NodeType.IntegerLiteralExpression:
- if (0 == ((IntegerLiteralExpression) initializer).Value) {
- node.Initializer = null;
- return;
- }
- break;
- case NodeType.BoolLiteralExpression:
- if (false == ((BoolLiteralExpression) initializer).Value) {
- node.Initializer = null;
- return;
- }
- break;
- case NodeType.DoubleLiteralExpression:
- if (0.0f == ((DoubleLiteralExpression) initializer).Value) {
- node.Initializer = null;
- return;
- }
- break;
- }
-
- Method method = GetInitializerMethod(node);
- method.Body.Add(
- CodeBuilder.CreateAssignment(
- initializer.LexicalInfo,
- CodeBuilder.CreateReference(node),
- initializer));
- node.Initializer = null;
- }
-
- Method CreateInitializerMethod(TypeDefinition type, string name, TypeMemberModifiers modifiers)
- {
- Method method = CodeBuilder.CreateMethod(name, TypeSystemServices.VoidType, modifiers);
- type.Members.Add(method);
- MarkVisited(method);
- return method;
- }
-
- private Field GetFieldsInitializerInitializedField(TypeDefinition type)
- {
- string name = AstUtil.BuildUniqueTypeMemberName(type, "initialized");
- Field field= (Field) type.Members[name];
-
- if (null == field)
- {
- field = CodeBuilder.CreateField(name, TypeSystemServices.BoolType);
- field.Visibility = TypeMemberModifiers.Private;
- type.Members.Add(field);
- MarkVisited(field);
- }
- return field;
- }
-
- Method GetInitializerMethod(Field node)
- {
- return GetInitializerFor(node.DeclaringType, node.IsStatic);
- }
-
- private Method GetInitializerFor(TypeDefinition type, bool isStatic)
- {
- string methodName = isStatic ? "$static_initializer$" : "$initializer$";
- Method method = (Method)type[methodName];
- if (null == method)
- {
- if (isStatic)
- {
- if (!type.HasStaticConstructor)
- {
- // when the class doesnt have a static constructor
- // yet, create one and use it as the static
- // field initializer method
- method = CodeBuilder.CreateStaticConstructor(type);
- }
- else
- {
- method = CreateInitializerMethod(type, methodName, TypeMemberModifiers.Static);
- AddInitializerToStaticConstructor(type, (InternalMethod)method.Entity);
- }
- }
- else
- {
- method = CreateInitializerMethod(type, methodName, TypeMemberModifiers.None);
- }
- type[methodName] = method;
- }
- return method;
- }
-
- void AddInitializerToStaticConstructor(TypeDefinition type, InternalMethod initializer)
- {
- GetStaticConstructor(type).Body.Insert(0,
- CodeBuilder.CreateMethodInvocation(initializer));
- }
-
- void AddInitializerToInstanceConstructors(TypeDefinition type, Method initializer)
- {
- int n = 0;
-
- //count number of non-static constructors
- foreach (TypeMember node in type.Members)
- {
- if (NodeType.Constructor == node.NodeType && !node.IsStatic)
- n++;
- }
-
- //if there is more than one we need $initialized$ guard check
- if (n > 1)
- AddInitializedGuardToInitializer(type, initializer);
-
- foreach (TypeMember node in type.Members)
- {
- if (NodeType.Constructor == node.NodeType && !node.IsStatic)
- {
- Constructor constructor = (Constructor) node;
- n = GetIndexAfterSuperInvocation(constructor.Body);
- foreach (Statement st in initializer.Body.Statements)
- {
- constructor.Body.Insert(n, (Statement) st.Clone());
- n++;
- }
- foreach (Local loc in initializer.Locals)
- {
- constructor.Locals.Add(loc);
- }
- }
- }
- }
-
- void AddInitializedGuardToInitializer(TypeDefinition type, Method initializer)
- {
- Field field = GetFieldsInitializerInitializedField(type);
-
- //run initializer code only if $initialized$ is false
- //hmm quasi-notation would be lovely here
- Block trueBlock = new Block();
- trueBlock.Add(new GotoStatement(LexicalInfo.Empty, new ReferenceExpression("___initialized___")));
- IfStatement cond = new IfStatement(CodeBuilder.CreateReference(field),
- trueBlock, null);
- initializer.Body.Insert(0, cond);
-
- //set $initialized$ field to true
- initializer.Body.Add(
- CodeBuilder.CreateFieldAssignment(field, new BoolLiteralExpression(true)));
-
- //label we're past the initializer
- initializer.Body.Add(
- new LabelStatement(LexicalInfo.Empty, "___initialized___"));
- }
-
- int GetIndexAfterSuperInvocation(Block body)
- {
- int index = 0;
- foreach (Statement s in body.Statements)
- {
- if (NodeType.ExpressionStatement == s.NodeType)
- {
- Expression expression = ((ExpressionStatement)s).Expression;
- if (NodeType.MethodInvocationExpression == expression.NodeType)
- {
- if (NodeType.SuperLiteralExpression == ((MethodInvocationExpression)expression).Target.NodeType)
- {
- return index + 1;
- }
- }
- }
- ++index;
- }
- return 0;
- }
-
- Constructor GetStaticConstructor(TypeDefinition type)
- {
- return CodeBuilder.GetOrCreateStaticConstructorFor(type);
- }
-
- void CheckRuntimeMethod(Method method)
- {
- if (method.Body.IsEmpty) return;
-
- Error(CompilerErrorFactory.RuntimeMethodBodyMustBeEmpty(method, GetEntity(method)));
- }
-
- //ECMA-335 Partition III Section 1.8.1.4
- //cannot call an instance method before super/self.
- void CheckInstanceMethodInvocationsWithinConstructor(Constructor ctor)
- {
- if (ctor.Body.IsEmpty)
- return;
-
- foreach (Statement st in ctor.Body.Statements)
- {
- ExpressionStatement est = st as ExpressionStatement;
- if (null == est) continue;
-
- MethodInvocationExpression mie = est.Expression as MethodInvocationExpression;
- if (null == mie) continue;
-
- if (mie.Target is SelfLiteralExpression
- || mie.Target is SuperLiteralExpression)
- break;//okay we're done checking
-
- if (mie.Target is MemberReferenceExpression)
- {
- MemberReferenceExpression mre = (MemberReferenceExpression) mie.Target;
- if (mre.Target is SelfLiteralExpression
- || mre.Target is SuperLiteralExpression)
- {
- Error(CompilerErrorFactory.InstanceMethodInvocationBeforeInitialization(ctor, mre));
- }
- }
- }
- }
-
- override public void OnConstructor(Constructor node)
- {
- if (WasVisited(node))
- {
- return;
- }
- MarkVisited(node);
-
- Visit(node.Attributes);
- Visit(node.Parameters);
-
- InternalConstructor entity = (InternalConstructor)node.Entity;
- ProcessMethodBody(entity);
-
- if (node.IsRuntime)
- {
- CheckRuntimeMethod(node);
- }
- else
- {
- if (entity.DeclaringType.IsValueType)
- {
- if (0 == node.Parameters.Count
- && !node.IsStatic
- && !node.IsSynthetic)
- {
- Error(CompilerErrorFactory.ValueTypesCannotDeclareParameterlessConstructors(node));
- }
- }
- else if (
- !entity.HasSelfCall &&
- !entity.HasSuperCall &&
- !entity.IsStatic)
- {
- IType baseType = entity.DeclaringType.BaseType;
- IConstructor super = GetCorrectConstructor(node, baseType, EmptyExpressionCollection);
- if (null != super)
- {
- node.Body.Statements.Insert(0,
- CodeBuilder.CreateSuperConstructorInvocation(super));
- }
- }
- if (!entity.IsStatic)
- CheckInstanceMethodInvocationsWithinConstructor(node);
- }
- }
-
- override public void LeaveParameterDeclaration(ParameterDeclaration node)
- {
- AssertIdentifierName(node, node.Name);
- CheckParameterType(node.Type);
- }
-
- void CheckParameterType(TypeReference type)
- {
- if (type.Entity != VoidType()) return;
- Error(CompilerErrorFactory.InvalidParameterType(type, VoidType()));
- }
-
- private IType VoidType()
- {
- return TypeSystemServices.VoidType;
- }
-
- void CheckFieldType(TypeReference type)
- {
- if (type.Entity != VoidType()) return;
- Error(CompilerErrorFactory.InvalidFieldType(type, VoidType()));
- }
-
- bool CheckDeclarationType(TypeReference type)
- {
- if (type.Entity != VoidType()) return true;
- Error(CompilerErrorFactory.InvalidDeclarationType(type, VoidType()));
- return false;
- }
-
- override public void OnBlockExpression(BlockExpression node)
- {
- if (WasVisited(node)) return;
- if (ShouldDeferClosureProcessing(node)) return;
-
- InferClosureSignature(node);
- ProcessClosureBody(node);
- }
-
- private void InferClosureSignature(BlockExpression node)
- {
- ClosureSignatureInferrer inferrer = new ClosureSignatureInferrer(node);
- ICallableType inferredCallableType = inferrer.InferCallableType();
- BindExpressionType(node, inferredCallableType);
- AddInferredClosureParameterTypes(node, inferredCallableType);
- }
-
- private bool ShouldDeferClosureProcessing(BlockExpression node)
- {
- // Defer closure processing if it's an argument in a generic method invocation
- MethodInvocationExpression methodInvocationContext = node.ParentNode as MethodInvocationExpression;
- if (methodInvocationContext == null) return false;
- if (!methodInvocationContext.Arguments.Contains(node)) return false;
-
- if (methodInvocationContext.Target.Entity is Ambiguous)
- return ((Ambiguous) methodInvocationContext.Target.Entity).Any(GenericsServices.IsGenericMethod);
-
- IMethod target = methodInvocationContext.Target.Entity as IMethod;
- return (target != null && GenericsServices.IsGenericMethod(target));
- }
-
- private void AddInferredClosureParameterTypes(BlockExpression node, ICallableType callableType)
- {
- IParameter[] parameters = (callableType == null ? null : callableType.GetSignature().Parameters);
- for (int i = 0; i < node.Parameters.Count; i++)
- {
- ParameterDeclaration pd = node.Parameters[i];
- if (pd.Type != null) continue;
-
- IType inferredType;
- if (parameters != null && i < parameters.Length)
- {
- inferredType = parameters[i].Type;
- }
- else if (pd.IsParamArray)
- {
- inferredType = TypeSystemServices.ObjectArrayType;
- }
- else
- {
- inferredType = TypeSystemServices.ObjectType;
- }
-
- pd.Type = CodeBuilder.CreateTypeReference(inferredType);
- }
- }
-
- void ProcessClosureBody(BlockExpression node)
- {
- MarkVisited(node);
- if (node.ContainsAnnotation("inline"))
- AddOptionalReturnStatement(node.Body);
-
- var explicitClosureName = node[BlockExpression.ClosureNameAnnotation] as string;
-
- Method closure = CodeBuilder.CreateMethod(
- ClosureName(explicitClosureName),
- node.ReturnType ?? CodeBuilder.CreateTypeReference(Unknown.Default),
- ClosureModifiers());
-
- MarkVisited(closure);
-
- var closureEntity = (InternalMethod)closure.Entity;
- closure.LexicalInfo = node.LexicalInfo;
- closure.Parameters = node.Parameters;
- closure.Body = node.Body;
-
- CurrentMethod.DeclaringType.Members.Add(closure);
-
- CodeBuilder.BindParameterDeclarations(_currentMethod.IsStatic, closure);
-
- // check for invalid names and
- // resolve parameter types
- Visit(closure.Parameters);
-
- // Inside the closure, connect the closure method namespace with the current namespace
- var ns = new NamespaceDelegator(CurrentNamespace, closureEntity);
-
- // Allow closure body to reference itself using its explicit name (BOO-1085)
- if (explicitClosureName != null)
- ns.DelegateTo(new AliasedNamespace(explicitClosureName, closureEntity));
-
- ProcessMethodBody(closureEntity, ns);
-
- if (closureEntity.ReturnType is Unknown)
- TryToResolveReturnType(closureEntity);
-
- node.ExpressionType = closureEntity.Type;
- node.Entity = closureEntity;
- }
-
- protected Method CurrentMethod
- {
- get { return _currentMethod.Method; }
- }
-
- private void ProcessClosureInMethodInvocation(GenericParameterInferrer inferrer, BlockExpression closure, ICallableType formalType)
- {
- var sig = formalType.GetSignature();
-
- var replacer = new TypeReplacer();
- var collector = new TypeCollector(delegate(IType t)
- {
- IGenericParameter gp = t as IGenericParameter;
- if (gp == null) return false;
- return gp.DeclaringEntity == inferrer.GenericMethod;
- });
-
- collector.Visit(formalType);
- foreach (var typeParameter in collector.Matches)
- {
- var inferredType = inferrer.GetInferredType((IGenericParameter)typeParameter);
- if (inferredType != null)
- replacer.Replace(typeParameter, inferredType);
- }
-
- for (var i = 0; i < sig.Parameters.Length; i++)
- {
- var pd = closure.Parameters[i];
- if (pd.Type != null) continue;
- pd.Type = CodeBuilder.CreateTypeReference(replacer.MapType(sig.Parameters[i].Type));
- }
-
- ProcessClosureBody(closure);
- }
-
- private TypeMemberModifiers ClosureModifiers()
- {
- var modifiers = TypeMemberModifiers.Internal;
- if (_currentMethod.IsStatic)
- modifiers |= TypeMemberModifiers.Static;
- return modifiers;
- }
-
- private string ClosureName(string explicitName)
- {
- string closureHint = explicitName ?? "closure";
- return Context.GetUniqueName(_currentMethod.Name, closureHint);
- }
-
- private static void AddOptionalReturnStatement(Block body)
- {
- if (body.Statements.Count != 1) return;
- var stmt = body.FirstStatement as ExpressionStatement;
- if (null == stmt) return;
-
- var rs = new ReturnStatement(stmt.LexicalInfo, stmt.Expression, null);
- rs.Annotate(OptionalReturnStatementAnnotation);
- body.Replace(stmt, rs);
- }
-
- override public void OnMethod(Method method)
- {
- if (WasVisited(method)) return;
- MarkVisited(method);
-
- Visit(method.Attributes);
- Visit(method.Parameters);
- Visit(method.ReturnType);
- Visit(method.ReturnTypeAttributes);
-
- bool ispinvoke = GetEntity(method).IsPInvoke;
- if (method.IsRuntime || ispinvoke)
- {
- CheckRuntimeMethod(method);
- if (ispinvoke)
- {
- method.Modifiers |= TypeMemberModifiers.Static;
- }
- }
- else
- {
- try
- {
- PushMember(method);
- ProcessRegularMethod(method);
- }
- finally
- {
- PopMember();
- }
- }
- }
-
- void CheckIfIsMethodOverride(InternalMethod method)
- {
- if (method.IsStatic) return;
- if (method.IsNew) return;
-
- var overriden = FindMethodOverridenBy(method);
- if (overriden == null) return;
-
- if (CanBeOverriden(overriden))
- ProcessMethodOverride(method, overriden);
- else if (InStrictMode())
- CantOverrideNonVirtual(method.Method, overriden);
- else
- MethodHidesInheritedNonVirtual(method, overriden);
- }
-
- private bool InStrictMode()
- {
- return Parameters.Strict;
- }
-
- private void MethodHidesInheritedNonVirtual(InternalMethod hidingMethod, IMethod hiddenMethod)
- {
- Warnings.Add(CompilerWarningFactory.MethodHidesInheritedNonVirtual(hidingMethod.Method, hidingMethod, hiddenMethod));
- }
-
- IMethod FindPropertyAccessorOverridenBy(Property property, Method accessor)
- {
- var baseProperty = ((InternalProperty)property.Entity).Overriden;
- if (baseProperty == null)
- return null;
-
- var baseAccessor = property.Getter == accessor ? baseProperty.GetGetMethod() : baseProperty.GetSetMethod();
- if (baseAccessor != null && TypeSystemServices.CheckOverrideSignature((IMethod) accessor.Entity, baseAccessor))
- return baseAccessor;
-
- return null;
- }
-
- IMethod FindMethodOverridenBy(InternalMethod entity)
- {
- var method = entity.Method;
- if (method.ParentNode.NodeType == NodeType.Property)
- return FindPropertyAccessorOverridenBy((Property)method.ParentNode, method);
-
- var baseType = entity.DeclaringType.BaseType;
- var candidates = NameResolutionService.Resolve(baseType, entity.Name, EntityType.Method);
- if (candidates == null)
- return null;
-
- var baseMethod = FindMethodOverridenBy(entity, candidates);
- if (baseMethod != null) EnsureRelatedNodeWasVisited(method, baseMethod);
- return baseMethod;
- }
-
- private static IMethod FindMethodOverridenBy(InternalMethod entity, IEntity candidates)
- {
- if (EntityType.Method == candidates.EntityType)
- {
- var candidate = (IMethod)candidates;
- if (TypeSystemServices.CheckOverrideSignature(entity, candidate))
- return candidate;
- }
-
- if (candidates.IsAmbiguous())
- foreach (IMethod candidate in ((Ambiguous) candidates).Entities)
- if (TypeSystemServices.CheckOverrideSignature(entity, candidate))
- return candidate;
-
- return null;
- }
-
- void ResolveMethodOverride(InternalMethod entity)
- {
- var baseMethod = FindMethodOverridenBy(entity);
- if (baseMethod == null)
- {
- var suggestion = GetMostSimilarBaseMethodName(entity);
- if (suggestion == entity.Name) //same name => incompatible signature
- Error(CompilerErrorFactory.NoMethodToOverride(entity.Method, entity, true));
- else //suggestion (or null)
- Error(CompilerErrorFactory.NoMethodToOverride(entity.Method, entity, suggestion));
- }
- else
- ValidateOverride(entity, baseMethod);
- }
-
- private string GetMostSimilarBaseMethodName(InternalMethod entity)
- {
- return NameResolutionService.GetMostSimilarMemberName(entity.DeclaringType.BaseType, entity.Name, EntityType.Method);
- }
-
- private void ValidateOverride(InternalMethod entity, IMethod baseMethod)
- {
- if (CanBeOverriden(baseMethod))
- ProcessMethodOverride(entity, baseMethod);
- else
- CantOverrideNonVirtual(entity.Method, baseMethod);
- }
-
- private bool CanBeOverriden(IMethod baseMethod)
- {
- return baseMethod.IsVirtual && !baseMethod.IsFinal;
- }
-
- void ProcessMethodOverride(InternalMethod entity, IMethod baseMethod)
- {
- CallableSignature baseSignature = TypeSystemServices.GetOverriddenSignature(baseMethod, entity);
-
- if (TypeSystemServices.IsUnknown(entity.ReturnType))
- {
- entity.Method.ReturnType = CodeBuilder.CreateTypeReference(entity.Method.LexicalInfo, baseSignature.ReturnType);
- }
- else if (baseSignature.ReturnType != entity.ReturnType)
- {
- Error(CompilerErrorFactory.InvalidOverrideReturnType(
- entity.Method.ReturnType,
- baseMethod,
- baseMethod.ReturnType,
- entity.ReturnType));
- }
- SetOverride(entity, baseMethod);
- }
-
- void CantOverrideNonVirtual(Method method, IMethod baseMethod)
- {
- Error(CompilerErrorFactory.CantOverrideNonVirtual(method, baseMethod));
- }
-
- static void SetPropertyAccessorOverride(Method accessor)
- {
- if (null == accessor) return;
- accessor.Modifiers |= TypeMemberModifiers.Override;
- }
-
- IProperty ResolvePropertyOverride(IProperty p, IEntity[] candidates)
- {
- foreach (IEntity candidate in candidates)
- {
- if (EntityType.Property != candidate.EntityType) continue;
- IProperty candidateProperty = (IProperty)candidate;
- if (CheckOverrideSignature(p, candidateProperty))
- {
- return candidateProperty;
- }
- }
- return null;
- }
-
- static bool CheckOverrideSignature(IProperty p, IProperty candidate)
- {
- return TypeSystemServices.CheckOverrideSignature(p.GetParameters(), candidate.GetParameters());
- }
-
- void ResolvePropertyOverride(Property property)
- {
- var overriden = FindPropertyOverridenBy(property);
- if (overriden == null)
- return;
-
- EntityFor(property).Overriden = overriden;
- EnsureRelatedNodeWasVisited(property, overriden);
- PropagateOverrideToAccessors(property);
-
- if (property.Type == null)
- property.Type = CodeBuilder.CreateTypeReference(EntityFor(property).Overriden.Type);
- }
-
- private void PropagateOverrideToAccessors(Property property)
- {
- if (property.IsOverride)
- {
- SetPropertyAccessorOverride(property.Getter);
- SetPropertyAccessorOverride(property.Setter);
- return;
- }
-
- var overridenProperty = EntityFor(property).Overriden;
- if (overridenProperty.GetGetMethod() != null)
- SetPropertyAccessorOverride(property.Getter);
- if (overridenProperty.GetSetMethod() != null)
- SetPropertyAccessorOverride(property.Setter);
- }
-
- private InternalProperty EntityFor(Property property)
- {
- return ((InternalProperty) property.Entity);
- }
-
- private IProperty FindPropertyOverridenBy(Property property)
- {
- var baseType = EntityFor(property).DeclaringType.BaseType;
- var candidates = NameResolutionService.Resolve(baseType, property.Name, EntityType.Property);
- if (candidates != null)
- {
- if (EntityType.Property == candidates.EntityType)
- {
- var candidate = (IProperty)candidates;
- if (CheckOverrideSignature(EntityFor(property), candidate))
- return candidate;
- }
- else if (candidates.IsAmbiguous())
- return ResolvePropertyOverride(EntityFor(property), ((Ambiguous)candidates).Entities);
- }
- return null;
- }
-
- void SetOverride(InternalMethod entity, IMethod baseMethod)
- {
- TraceOverride(entity.Method, baseMethod);
-
- entity.Overriden = baseMethod;
- entity.Method.Modifiers |= TypeMemberModifiers.Override;
- }
-
-
- void TraceOverride(Method method, IMethod baseMethod)
- {
- _context.TraceInfo("{0}: Method '{1}' overrides '{2}'", method.LexicalInfo, method.Name, baseMethod);
- }
-
- sealed class ReturnExpressionFinder : FastDepthFirstVisitor
- {
- bool _hasReturnStatements;
-
- bool _hasYieldStatements;
-
- public ReturnExpressionFinder(Method node)
- {
- Visit(node.Body);
- }
-
- public bool HasReturnStatements
- {
- get { return _hasReturnStatements; }
- }
-
- public bool HasYieldStatements
- {
- get { return _hasYieldStatements; }
- }
-
- public override void OnReturnStatement(ReturnStatement node)
- {
- _hasReturnStatements |= (null != node.Expression);
- }
-
- public override void OnYieldStatement(YieldStatement node)
- {
- _hasYieldStatements = true;
- }
- }
-
- protected bool HasNeitherReturnNorYield(Method node)
- {
- var finder = new ReturnExpressionFinder(node);
- return !(finder.HasReturnStatements || finder.HasYieldStatements);
- }
-
- void PreProcessMethod(Method node)
- {
- if (WasAlreadyPreProcessed(node))
- return;
-
- MarkPreProcessed(node);
-
- var entity = (InternalMethod)GetEntity(node);
- if (node.IsOverride)
- ResolveMethodOverride(entity);
- else
- {
- CheckIfIsMethodOverride(entity);
- if (TypeSystemServices.IsUnknown(entity.ReturnType) && HasNeitherReturnNorYield(node))
- node.ReturnType = CodeBuilder.CreateTypeReference(node.LexicalInfo, TypeSystemServices.VoidType);
- }
- }
-
- static readonly object PreProcessedKey = new object();
-
- private static bool WasAlreadyPreProcessed(Method node)
- {
- return node.ContainsAnnotation(PreProcessedKey);
- }
-
- private static void MarkPreProcessed(Method node)
- {
- node[PreProcessedKey] = PreProcessedKey;
- }
-
- void ProcessRegularMethod(Method node)
- {
- PreProcessMethod(node);
-
- var entity = (InternalMethod) GetEntity(node);
- ProcessMethodBody(entity);
-
- PostProcessMethod(node);
- }
-
- private void PostProcessMethod(Method node)
- {
- var parentIsClass = node.DeclaringType.NodeType == NodeType.ClassDefinition;
- if (!parentIsClass) return;
-
- var entity = (InternalMethod)GetEntity(node);
- if (TypeSystemServices.IsUnknown(entity.ReturnType))
- TryToResolveReturnType(entity);
- else
- {
- if (entity.IsGenerator)
- {
- CheckGeneratorReturnType(node, entity.ReturnType);
- CheckGeneratorYieldType(entity, entity.ReturnType);
- }
- }
- CheckGeneratorCantReturnValues(entity);
- }
-
- void CheckGeneratorCantReturnValues(InternalMethod entity)
- {
- if (!entity.IsGenerator) return;
- if (null == entity.ReturnExpressions) return;
-
- foreach (Expression e in entity.ReturnExpressions)
- {
- Error(CompilerErrorFactory.GeneratorCantReturnValue(e));
- }
- }
-
- void CheckGeneratorReturnType(Method method, IType returnType)
- {
- bool validReturnType =
- (TypeSystemServices.IEnumerableType == returnType ||
- TypeSystemServices.IEnumeratorType == returnType ||
- TypeSystemServices.IsSystemObject(returnType) ||
- TypeSystemServices.IsGenericGeneratorReturnType(returnType));
-
- if (!validReturnType)
- {
- Error(CompilerErrorFactory.InvalidGeneratorReturnType(method.ReturnType, returnType));
- }
- }
-
- void CheckGeneratorYieldType(InternalMethod method, IType returnType)
- {
- if (!TypeSystemServices.IsGenericGeneratorReturnType(returnType))
- return;
-
- IType returnElementType = returnType.ConstructedInfo.GenericArguments[0];
- foreach (var yieldExpression in method.YieldExpressions)
- {
- var yieldType = yieldExpression.ExpressionType;
- if (!IsAssignableFrom(returnElementType, yieldType) &&
- !TypeSystemServices.CanBeReachedByDownCastOrPromotion(returnElementType, yieldType))
- {
- Error(CompilerErrorFactory.YieldTypeDoesNotMatchReturnType(
- yieldExpression, yieldType, returnElementType));
- }
- }
- }
-
- void ProcessMethodBody(InternalMethod entity)
- {
- ProcessMethodBody(entity, entity);
- }
-
- void ProcessMethodBody(InternalMethod entity, INamespace ns)
- {
- ProcessNodeInMethodContext(entity, ns, entity.Method.Body);
- }
-
- void ProcessNodeInMethodContext(InternalMethod entity, INamespace ns, Node node)
- {
- PushMethodInfo(entity);
- EnterNamespace(ns);
- try
- {
- Visit(node);
- }
- finally
- {
- LeaveNamespace();
- PopMethodInfo();
- }
- }
-
- void ResolveGeneratorReturnType(InternalMethod entity)
- {
- IType returnType = GetGeneratorReturnType(entity);
- entity.Method.ReturnType = CodeBuilder.CreateTypeReference(returnType);
- }
-
- /// <summary>
- /// Allows a different language to use custom rules for generator
- /// return types.
- /// </summary>
- /// <param name="generator"></param>
- /// <returns></returns>
- protected virtual IType GetGeneratorReturnType(InternalMethod generator)
- {
- // Make method return a generic IEnumerable
- return GeneratorTypeOf(GeneratorItemTypeFor(generator));
- }
-
- private IType GeneratorItemTypeFor(InternalMethod generator)
- {
- return My<GeneratorItemTypeInferrer>.Instance.GeneratorItemTypeFor(generator);
- }
-
- void TryToResolveReturnType(InternalMethod entity)
- {
- if (entity.IsGenerator)
- {
- ResolveGeneratorReturnType(entity);
- return;
- }
-
- if (CanResolveReturnType(entity))
- ResolveReturnType(entity);
- }
-
- override public void OnSuperLiteralExpression(SuperLiteralExpression node)
- {
- if (!AstUtil.IsTargetOfMethodInvocation(node))
- {
- node.ExpressionType = _currentMethod.DeclaringType.BaseType;
- return;
- }
-
- if (EntityType.Constructor == _currentMethod.EntityType)
- {
- // TODO: point to super ctor
- node.Entity = _currentMethod;
- return;
- }
-
- if (null == _currentMethod.Overriden)
- {
- Error(node,
- CompilerErrorFactory.MethodIsNotOverride(node, _currentMethod));
- return;
- }
-
- node.Entity = _currentMethod.Overriden;
- }
-
- static bool CanResolveReturnType(InternalMethod method)
- {
- var expressions = method.ReturnExpressions;
- if (null != expressions)
- {
- foreach (var expression in expressions)
- {
- IType type = expression.ExpressionType;
- if (type == null || TypeSystemServices.IsUnknown(type))
- return false;
- }
- }
- return true;
- }
-
- void ResolveReturnType(InternalMethod entity)
- {
- var method = entity.Method;
- method.ReturnType = entity.ReturnExpressions == null
- ? CodeBuilder.CreateTypeReference(TypeSystemServices.VoidType)
- : GetMostGenericTypeReference(entity.ReturnExpressions);
- TraceReturnType(method, entity);
- }
-
- private TypeReference GetMostGenericTypeReference(ExpressionCollection expressions)
- {
- var type = MapWildcardType(GetMostGenericType(expressions));
- return CodeBuilder.CreateTypeReference(type);
- }
-
- IType MapWildcardType(IType type)
- {
- return TypeSystemServices.MapWildcardType(type);
- }
-
- IType GetMostGenericType(IType lhs, IType rhs)
- {
- return TypeSystemServices.GetMostGenericType(lhs, rhs);
- }
-
- IType GetMostGenericType(ExpressionCollection args)
- {
- return TypeSystemServices.GetMostGenericType(args);
- }
-
- override public void OnBoolLiteralExpression(BoolLiteralExpression node)
- {
- BindExpressionType(node, TypeSystemServices.BoolType);
- }
-
- override public void OnTimeSpanLiteralExpression(TimeSpanLiteralExpression node)
- {
- BindExpressionType(node, TypeSystemServices.TimeSpanType);
- }
-
- override public void OnIntegerLiteralExpression(IntegerLiteralExpression node)
- {
- BindExpressionType(node, node.IsLong ? TypeSystemServices.LongType : TypeSystemServices.IntType);
- }
-
- override public void OnDoubleLiteralExpression(DoubleLiteralExpression node)
- {
- BindExpressionType(node, node.IsSingle ? TypeSystemServices.SingleType : TypeSystemServices.DoubleType);
- }
-
- override public void OnStringLiteralExpression(StringLiteralExpression node)
- {
- BindExpressionType(node, TypeSystemServices.StringType);
- }
-
- override public void OnCharLiteralExpression(CharLiteralExpression node)
- {
- CheckCharLiteralValue(node);
- BindExpressionType(node, TypeSystemServices.CharType);
- }
-
- private void CheckCharLiteralValue(CharLiteralExpression node)
- {
- var value = node.Value;
- if (value == null || value.Length != 1)
- Errors.Add(CompilerErrorFactory.InvalidCharLiteral(node, value));
- }
-
- static IEntity[] GetSetMethods(IEntity[] entities)
- {
- return GetPropertyAccessors(entities, p => p.GetSetMethod());
- }
-
- private static IEntity[] GetGetMethods(IEntity[] entities)
- {
- return GetPropertyAccessors(entities, p => p.GetGetMethod());
- }
-
- private static IEntity[] GetPropertyAccessors(IEntity[] entities, Func<IProperty, IEntity> selector)
- {
- return entities.OfType<IProperty>().Select(selector).Distinct().ToArray();
- }
-
- void AssertIsNotComplexSlicing(SlicingExpression node)
- {
- if (node.IsComplexSlicing())
- NotImplemented(node, "complex slicing");
- }
-
- protected MethodInvocationExpression CreateEquals(BinaryExpression node)
- {
- return CodeBuilder.CreateMethodInvocation(MethodCache.RuntimeServices_EqualityOperator, node.Left, node.Right);
- }
-
- protected bool IsIndexedProperty(Expression expression)
- {
- return expression.Entity.IsIndexedProperty();
- }
-
- override public void LeaveSlicingExpression(SlicingExpression node)
- {
- if (node.Target.Entity.IsAmbiguous())
- {
- BindIndexedPropertySlicing(node);
- return;
- }
-
- // target[indices]
- var targetType = GetExpressionType(node.Target);
- if (IsError(targetType))
- {
- Error(node);
- return;
- }
-
- if (node.IsComplexSlicing())
- {
- BindExpressionType(node, ResultingTypeForComplexSlicing(node));
- return;
- }
-
- if (IsIndexedProperty(node.Target))
- {
- BindIndexedPropertySlicing(node);
- return;
- }
-
- if (targetType.IsArray)
- {
- BindExpressionType(node, targetType.ElementType);
- return;
- }
-
- var member = TypeSystemServices.GetDefaultMember(targetType);
- if (member == null)
- {
- Error(node, CompilerErrorFactory.TypeDoesNotSupportSlicing(node.Target, targetType));
- return;
- }
-
- node.Target = new MemberReferenceExpression(node.LexicalInfo, node.Target, member.Name)
- {
- Entity = member,
- ExpressionType = Null.Default // to be resolved later
- };
- SliceMember(node, member);
- }
-
- private IType ResultingTypeForComplexSlicing(SlicingExpression node)
- {
- var targetType = GetExpressionType(node.Target);
- return targetType.IsArray ? ResultingTypeForArraySlicing(node) : targetType;
- }
-
- IType ResultingTypeForArraySlicing(SlicingExpression node)
- {
- var arrayType = GetExpressionType(node.Target);
- if (node.Indices.Count > 1)
- {
- var collapseCount = node.Indices.Count(t => t.End == null);
- return arrayType.ElementType.MakeArrayType(node.Indices.Count - collapseCount);
- }
- return arrayType;
- }
-
- private void BindIndexedPropertySlicing(SlicingExpression node)
- {
- AssertIsNotComplexSlicing(node);
- SliceMember(node, node.Target.Entity);
- }
-
- void SliceMember(SlicingExpression node, IEntity member)
- {
- EnsureRelatedNodeWasVisited(node, member);
- if (node.IsTargetOfAssignment())
- {
- // leave it to LeaveBinaryExpression to resolve
- Bind(node, member);
- return;
- }
-
- MethodInvocationExpression mie = new MethodInvocationExpression(node.LexicalInfo);
- foreach (Slice index in node.Indices)
- {
- mie.Arguments.Add(index.Begin);
- }
-
- IMethod getter = null;
- if (member.IsAmbiguous())
- {
- IEntity result = ResolveAmbiguousPropertyReference((ReferenceExpression)node.Target, (Ambiguous)member, mie.Arguments);
- IProperty found = result as IProperty;
- if (null != found)
- {
- getter = found.GetGetMethod();
- }
- else if (result.IsAmbiguous())
- {
- Error(node);
- return;
- }
- }
- else if (EntityType.Property == member.EntityType)
- {
- getter = ((IProperty)member).GetGetMethod();
- }
-
- if (null != getter)
- {
- if (AssertParameters(node, getter, mie.Arguments))
- {
- Expression target = GetIndexedPropertySlicingTarget(node);
-
- mie.Target = CodeBuilder.CreateMemberReference(target, getter);
- BindExpressionType(mie, getter.ReturnType);
-
- node.ParentNode.Replace(node, mie);
- }
- else
- {
- Error(node);
- }
- }
- else
- {
- NotImplemented(node, "slice for anything but arrays and default properties");
- }
- }
-
- private Expression GetIndexedPropertySlicingTarget(SlicingExpression node)
- {
- Expression target = node.Target;
- MemberReferenceExpression mre = target as MemberReferenceExpression;
- if (null != mre) return mre.Target;
- return CreateSelfReference();
- }
-
- override public void LeaveExpressionInterpolationExpression(ExpressionInterpolationExpression node)
- {
- BindExpressionType(node, TypeSystemServices.StringType);
- }
-
- override public void LeaveListLiteralExpression(ListLiteralExpression node)
- {
- BindExpressionType(node, TypeSystemServices.ListType);
- TypeSystemServices.MapToConcreteExpressionTypes(node.Items);
- }
-
- override public void OnExtendedGeneratorExpression(ExtendedGeneratorExpression node)
- {
- BlockExpression block = new BlockExpression(node.LexicalInfo);
-
- Block body = block.Body;
- Expression e = node.Items[0].Expression;
- foreach (GeneratorExpression ge in node.Items)
- {
- ForStatement fs = new ForStatement(ge.LexicalInfo);
- fs.Iterator = ge.Iterator;
- fs.Declarations = ge.Declarations;
-
- body.Add(fs);
-
- if (null == ge.Filter)
- {
- body = fs.Block;
- }
- else
- {
- fs.Block.Add(
- NormalizeStatementModifiers.MapStatementModifier(ge.Filter, out body));
- }
-
-
- }
- body.Add(new YieldStatement(e.LexicalInfo, e));
-
- MethodInvocationExpression mie = new MethodInvocationExpression(node.LexicalInfo);
- mie.Target = block;
-
- Node parentNode = node.ParentNode;
- bool isGenerator = AstUtil.IsListMultiGenerator(parentNode);
- parentNode.Replace(node, mie);
- mie.Accept(this);
-
- if (isGenerator)
- {
- parentNode.ParentNode.Replace(
- parentNode,
- CodeBuilder.CreateConstructorInvocation(
- TypeSystemServices.Map(ProcessGenerators.List_IEnumerableConstructor),
- mie));
- }
- }
-
- override public void OnGeneratorExpression(GeneratorExpression node)
- {
- Visit(node.Iterator);
- node.Iterator = ProcessIterator(node.Iterator, node.Declarations);
-
- EnterNamespace(new DeclarationsNamespace(CurrentNamespace, node.Declarations));
- Visit(node.Filter);
- Visit(node.Expression);
- LeaveNamespace();
-
- IType generatorItemType = TypeSystemServices.GetConcreteExpressionType(node.Expression);
- BindExpressionType(node, GeneratorTypeOf(generatorItemType));
- }
-
- private IType GeneratorTypeOf(IType generatorItemType)
- {
- if (generatorItemType == TypeSystemServices.VoidType)
- // cannot use 'void' as a generic argument
- return TypeSystemServices.ErrorEntity;
- return GetConstructedType(TypeSystemServices.IEnumerableGenericType, generatorItemType);
- }
-
- protected IType GetConstructedType(IType genericType, IType argType)
- {
- return genericType.GenericInfo.ConstructType(argType);
- }
-
- override public void LeaveHashLiteralExpression(HashLiteralExpression node)
- {
- BindExpressionType(node, TypeSystemServices.HashType);
- foreach (ExpressionPair pair in node.Items)
- {
- GetConcreteExpressionType(pair.First);
- GetConcreteExpressionType(pair.Second);
- }
- }
-
- override public void LeaveArrayLiteralExpression(ArrayLiteralExpression node)
- {
- TypeSystemServices.MapToConcreteExpressionTypes(node.Items);
-
- var type = InferArrayType(node);
- BindExpressionType(node, type);
-
- if (node.Type == null)
- node.Type = (ArrayTypeReference)CodeBuilder.CreateTypeReference(type);
- else
- CheckItems(type.ElementType, node.Items);
- }
-
- private IArrayType InferArrayType(ArrayLiteralExpression node)
- {
- if (null != node.Type) return (IArrayType)node.Type.Entity;
- if (node.Items.Count == 0) return EmptyArrayType.Default;
- return GetMostGenericType(node.Items).MakeArrayType(1);
- }
-
- override public void LeaveDeclaratio…
Large files files are truncated, but you can click here to view the full file