BooMethodBuilder CreateConstructor(BooClassBuilder builder) { BooMethodBuilder constructor = builder.AddConstructor(); constructor.Body.Add(CodeBuilder.CreateSuperConstructorInvocation(builder.Entity.BaseType)); return(constructor); }
public GeneratorSkeleton(BooClassBuilder generatorBuilder, BooMethodBuilder getEnumeratorBuilder, IType generatorItemType, GeneratorTypeReplacer generatorClassTypeReplacer) { GeneratorClassBuilder = generatorBuilder; GeneratorItemType = generatorItemType; GetEnumeratorBuilder = getEnumeratorBuilder; GeneratorClassTypeReplacer = generatorClassTypeReplacer; }
public override void LeaveTryStatement(TryStatement node) { TryStatementInfo info = _tryStatementStack.Pop(); if (info._containsYield) { ReplaceCurrentNode(info._replacement); TryStatementInfo currentTry = (_tryStatementStack.Count > 0) ? _tryStatementStack.Peek() : null; info._replacement.Add(node.ProtectedBlock); if (currentTry != null) { ConvertTryStatement(currentTry); info._replacement.Add(SetStateTo(currentTry._stateNumber)); } else { // leave try block, reset state to prevent ensure block from being called again info._replacement.Add(SetStateTo(_finishedStateNumber)); } BooMethodBuilder ensureMethod = _enumerator.AddMethod("$ensure" + info._stateNumber, TypeSystemServices.VoidType, TypeMemberModifiers.Private); ensureMethod.Body.Add(info._statement.EnsureBlock); info._ensureMethod = ensureMethod.Entity; info._replacement.Add(CallMethodOnSelf(ensureMethod.Entity)); _convertedTryStatements.Add(info); } }
public void DeclareFieldsAndConstructor(BooClassBuilder builder) { var keys = _referencedEntities.Keys.Cast <ITypedEntity>().ToArray(); foreach (var entity in keys) { _collector.Visit(entity.Type); } if (_collector.Matches.Any()) { BuildTypeMap(builder.ClassDefinition); } // referenced entities turn into fields foreach (var entity in keys) { Field field = builder.AddInternalField(GetUniqueName(entity.Name), _mapper.MapType(entity.Type)); _referencedEntities[entity] = (InternalField)field.Entity; } // single constructor taking all referenced entities BooMethodBuilder constructor = builder.AddConstructor(); constructor.Modifiers = TypeMemberModifiers.Public; constructor.Body.Add(CodeBuilder.CreateSuperConstructorInvocation(builder.Entity.BaseType)); foreach (var entity in _referencedEntities.Keys) { InternalField field = _referencedEntities[entity]; ParameterDeclaration parameter = constructor.AddParameter(field.Name, ((ITypedEntity)entity).Type); constructor.Body.Add( CodeBuilder.CreateAssignment(CodeBuilder.CreateReference(field), CodeBuilder.CreateReference(parameter))); } }
private BooMethodBuilder SetUpGetEnumeratorMethodBuilder(Node sourceNode, BooClassBuilder builder, IType generatorItemType) { BooMethodBuilder getEnumeratorBuilder = builder.AddVirtualMethod( "GetEnumerator", TypeSystemServices.IEnumeratorGenericType.GenericInfo.ConstructType(generatorItemType)); getEnumeratorBuilder.Method.LexicalInfo = sourceNode.LexicalInfo; return(getEnumeratorBuilder); }
void CreateReset() { BooMethodBuilder method = _enumerator.AddVirtualMethod("Reset", TypeSystemServices.VoidType); method.Body.Add( CodeBuilder.CreateAssignment( CodeBuilder.CreateReference((InternalField)_enumeratorField.Entity), CodeBuilder.CreateMethodInvocation(_generator.Iterator, TypeSystemServices.Map(Types.IEnumerable.GetMethod("GetEnumerator"))))); }
Field DeclareFieldInitializedFromConstructorParameter(BooClassBuilder type, BooMethodBuilder constructor, string parameterName, IType parameterType) { Field field = type.AddInternalField("$" + parameterName + _context.AllocIndex(), parameterType); InitializeFieldFromConstructorParameter(constructor, field, parameterName, parameterType); return(field); }
private void CreateClone() { BooMethodBuilder method = _enumerator.AddVirtualMethod("Clone", TypeSystemServices.ObjectType); method.Body.Add( new ReturnStatement( CodeBuilder.CreateMethodInvocation( CodeBuilder.CreateSelfReference(_enumerator.Entity), GetMemberwiseCloneMethod()))); }
Field DeclareFieldInitializedFromConstructorParameter(BooClassBuilder type, BooMethodBuilder constructor, string parameterName, IType parameterType) { Field field = type.AddInternalField(UniqueName(parameterName), parameterType); InitializeFieldFromConstructorParameter(constructor, field, parameterName, parameterType); return(field); }
public GeneratorMethodProcessor(CompilerContext context, InternalMethod method) : base(context, method) { var skeleton = My <GeneratorSkeletonBuilder> .Instance.SkeletonFor(method); _generatorItemType = skeleton.GeneratorItemType; _enumerable = skeleton.GeneratorClassBuilder; _getEnumeratorBuilder = skeleton.GetEnumeratorBuilder; _methodToEnumerableMapper = skeleton.GeneratorClassTypeReplacer; }
GeneratorSkeleton CreateGeneratorSkeleton(Node sourceNode, Method enclosingMethod, IType generatorItemType) { // create the class skeleton for type inference to work BooClassBuilder builder = SetUpEnumerableClassBuilder(sourceNode, enclosingMethod, generatorItemType); BooMethodBuilder getEnumeratorBuilder = SetUpGetEnumeratorMethodBuilder(sourceNode, builder, generatorItemType); enclosingMethod.DeclaringType.Members.Add(builder.ClassDefinition); return(new GeneratorSkeleton(builder, generatorItemType, getEnumeratorBuilder)); }
private void CreateDispose() { BooMethodBuilder dispose = _enumerator.AddVirtualMethod("Dispose", TypeSystemServices.VoidType); if (TypeCompatibilityRules.IsAssignableFrom(TypeSystemServices.IDisposableType, _sourceEnumeratorType)) { dispose.Body.Add(CodeBuilder.CreateMethodInvocation( CodeBuilder.CreateReference(_enumeratorField), Methods.InstanceActionOf <IDisposable>(d => d.Dispose))); } }
private void CreateDispose() { BooMethodBuilder dispose = _enumerator.AddVirtualMethod("Dispose", TypeSystemServices.VoidType); if (TypeSystemServices.Map(typeof(IDisposable)).IsAssignableFrom(_sourceEnumeratorType)) { dispose.Body.Add(CodeBuilder.CreateMethodInvocation( CodeBuilder.CreateReference(_enumeratorField), typeof(IDisposable).GetMethod("Dispose"))); } }
private IMethod CreateDisposeMethod() { BooMethodBuilder mn = _stateMachineClass.AddVirtualMethod("Dispose", TypeSystemServices.VoidType); mn.Method.LexicalInfo = this.LexicalInfo; var noEnsure = CodeBuilder.CreateLabel(_method.Method, "noEnsure").LabelStatement; mn.Body.Add(noEnsure); mn.Body.Add(SetStateTo(_finishedStateNumber)); mn.Body.Add(new ReturnStatement()); // Create a section calling all ensure methods for each converted try block var disposeLabels = new LabelStatement[_labels.Count]; foreach (var t in _convertedTryStatements) { var info = t; disposeLabels[info._stateNumber] = CodeBuilder.CreateLabel(_method.Method, "$ensure_" + info._stateNumber).LabelStatement; mn.Body.Add(disposeLabels[info._stateNumber]); mn.Body.Add(SetStateTo(_finishedStateNumber)); var block = mn.Body; while (info._parent != null) { TryStatement ts = new TryStatement(); block.Add(ts); ts.ProtectedBlock.Add(CallMethodOnSelf(info._ensureMethod)); block = ts.EnsureBlock = new Block(); info = info._parent; } block.Add(CallMethodOnSelf(info._ensureMethod)); mn.Body.Add(new ReturnStatement()); } // now map the labels of the suspended states to the labels we just created for (var i = 0; i < _labels.Count; i++) { if (_tryStatementInfoForLabels[i] == null) { disposeLabels[i] = noEnsure; } else { disposeLabels[i] = disposeLabels[_tryStatementInfoForLabels[i]._stateNumber]; } } mn.Body.Insert(0, CodeBuilder.CreateSwitch( this.LexicalInfo, CodeBuilder.CreateMemberReference(_state), disposeLabels)); return(mn.Entity); }
protected Field DeclareFieldInitializedFromConstructorParameter(BooClassBuilder type, BooMethodBuilder constructor, string parameterName, IType parameterType, TypeReplacer replacer) { var internalFieldType = replacer.MapType(parameterType); Field field = type.AddInternalField(UniqueName(parameterName), internalFieldType); InitializeFieldFromConstructorParameter(constructor, field, parameterName, internalFieldType); return(field); }
void InitializeFieldFromConstructorParameter(BooMethodBuilder constructor, Field field, string parameterName, IType parameterType) { ParameterDeclaration parameter = constructor.AddParameter(parameterName, parameterType); constructor.Body.Add( CodeBuilder.CreateAssignment( CodeBuilder.CreateReference(field), CodeBuilder.CreateReference(parameter))); }
private void CreateReset() { // Find GetEnumerator method on the source type IMethod getEnumerator = (IMethod)GetMember(_sourceEnumerableType, "GetEnumerator", EntityType.Method); // Build Reset method that calls GetEnumerator on the source BooMethodBuilder method = _enumerator.AddVirtualMethod("Reset", TypeSystemServices.VoidType); method.Body.Add( CodeBuilder.CreateAssignment( CodeBuilder.CreateReference((InternalField)_enumeratorField.Entity), CodeBuilder.CreateMethodInvocation(_generator.Iterator, getEnumerator))); }
public GeneratorMethodProcessor(CompilerContext context, InternalMethod method) { _labels = new List <LabelStatement>(); _mapping = new Hashtable(); _generator = method; GeneratorSkeleton skeleton = My <GeneratorSkeletonBuilder> .Instance.SkeletonFor(method); _generatorItemType = skeleton.GeneratorItemType; _enumerable = skeleton.GeneratorClassBuilder; _getEnumeratorBuilder = skeleton.GetEnumeratorBuilder; Initialize(context); }
void CreateGetEnumerator() { BooMethodBuilder method = (BooMethodBuilder)_generator["GetEnumeratorBuilder"]; MethodInvocationExpression mie = CodeBuilder.CreateConstructorInvocation(_enumerator.ClassDefinition); foreach (TypeMember member in _enumerable.ClassDefinition.Members) { if (NodeType.Field == member.NodeType) { IField field = (IField)member.Entity; mie.Arguments.Add(CodeBuilder.CreateMemberReference(field)); } } method.Body.Add(new ReturnStatement(mie)); }
void CreateMoveNext() { Method generator = _generator.Method; BooMethodBuilder mn = _enumerator.AddVirtualMethod("MoveNext", TypeSystemServices.BoolType); mn.Method.LexicalInfo = this.LexicalInfo; _moveNext = mn.Entity; foreach (Local local in generator.Locals) { InternalLocal entity = (InternalLocal)local.Entity; Field field = _enumerator.AddField("___" + entity.Name + _context.AllocIndex(), entity.Type); field.Modifiers |= TypeMemberModifiers.Internal; _mapping[entity] = field.Entity; } generator.Locals.Clear(); foreach (ParameterDeclaration parameter in generator.Parameters) { InternalParameter entity = (InternalParameter)parameter.Entity; if (entity.IsUsed) { Field field = DeclareFieldInitializedFromConstructorParameter(_enumerator, _enumeratorConstructor, entity.Name, entity.Type); _mapping[entity] = field.Entity; } } mn.Body.Add(CreateLabel(generator)); mn.Body.Add(generator.Body); generator.Body.Clear(); Visit(mn.Body); mn.Body.Add(CreateYieldInvocation(null)); mn.Body.Add(CreateLabel(generator)); mn.Body.Insert(0, CodeBuilder.CreateSwitch( this.LexicalInfo, CodeBuilder.CreateMemberReference(_state), _labels)); }
void CreateMoveNext() { Method generator = _generator.Method; BooMethodBuilder methodBuilder = _enumerator.AddVirtualMethod("MoveNext", TypeSystemServices.BoolType); methodBuilder.Method.LexicalInfo = generator.LexicalInfo; _moveNext = methodBuilder.Entity; TransformLocalsIntoFields(generator); TransformParametersIntoFieldsInitializedByConstructor(generator); methodBuilder.Body.Add(CreateLabel(generator)); // Visit() needs to know the number of the finished state _finishedStateNumber = _labels.Count; LabelStatement finishedLabel = CreateLabel(generator); methodBuilder.Body.Add(generator.Body); generator.Body.Clear(); Visit(methodBuilder.Body); methodBuilder.Body.Add(CreateYieldInvocation(LexicalInfo.Empty, _finishedStateNumber, null)); methodBuilder.Body.Add(finishedLabel); methodBuilder.Body.Insert(0, CodeBuilder.CreateSwitch( this.LexicalInfo, CodeBuilder.CreateMemberReference(_state), _labels)); // if the method contains converted try statements, put it in a try/failure block if (_convertedTryStatements.Count > 0) { IMethod dispose = CreateDisposeMethod(); var tryFailure = new TryStatement(); tryFailure.ProtectedBlock.Add(methodBuilder.Body); tryFailure.FailureBlock = new Block(); tryFailure.FailureBlock.Add(CallMethodOnSelf(dispose)); methodBuilder.Body.Clear(); methodBuilder.Body.Add(tryFailure); } }
private void CreateGetEnumerator() { BooMethodBuilder method = _skeleton.GetEnumeratorBuilder; MethodInvocationExpression mie = CodeBuilder.CreateConstructorInvocation(_enumerator.ClassDefinition); foreach (TypeMember member in _skeleton.GeneratorClassBuilder.ClassDefinition.Members) { if (NodeType.Field != member.NodeType) { continue; } IField field = (IField)member.Entity; mie.Arguments.Add(CodeBuilder.CreateMemberReference(field)); } method.Body.Add(new ReturnStatement(mie)); }
public void ChainConstructorsFromBaseType(BooClassBuilder builder) { foreach (IConstructor constructor in builder.Entity.BaseType.GetConstructors()) { ExpressionStatement stmt = this.CodeBuilder.CreateSuperConstructorInvocation(constructor); MethodInvocationExpression expression = stmt.Expression as MethodInvocationExpression; BooMethodBuilder builder2 = builder.AddConstructor(); int index = 0; IParameter[] parameters = constructor.GetParameters(); int length = parameters.Length; while (index < length) { ParameterDeclaration parameter = builder2.AddParameter(parameters[index].Name, parameters[index].Type); expression.Arguments.Add(this.CodeBuilder.CreateReference(parameter)); index++; } builder2.Body.Add(stmt); } }
public void DeclareFieldsAndConstructor(BooClassBuilder builder) { // referenced entities turn into fields foreach (ITypedEntity entity in Builtins.array(_referencedEntities.Keys)) { Field field = builder.AddField("__" + entity.Name + _context.AllocIndex(), entity.Type); field.Modifiers = TypeMemberModifiers.Internal; _referencedEntities[entity] = field.Entity; } // single constructor taking all referenced entities BooMethodBuilder constructor = builder.AddConstructor(); constructor.Body.Add(CodeBuilder.CreateSuperConstructorInvocation(builder.Entity.BaseType)); foreach (ITypedEntity entity in _referencedEntities.Keys) { InternalField field = (InternalField)_referencedEntities[entity]; ParameterDeclaration parameter = constructor.AddParameter(field.Name, entity.Type); constructor.Body.Add( CodeBuilder.CreateAssignment(CodeBuilder.CreateReference(field), CodeBuilder.CreateReference(parameter))); } }
void CreateEnumeratorConstructor() { _enumeratorConstructor = CreateConstructor(_enumerator); }
void CreateEnumerableConstructor() { _enumerableConstructor = CreateConstructor(_enumerable); }
private void CreateStateMachineConstructor() { _stateMachineConstructor = CreateConstructor(_stateMachineClass); }
ClassDefinition CreateAdaptor(ICallableType to, ICallableType from) { BooClassBuilder adaptor = CodeBuilder.CreateClass("$adaptor$" + from.Name + "$" + to.Name + "$" + _adaptors.Count); adaptor.AddBaseType(TypeSystemServices.ObjectType); adaptor.Modifiers = TypeMemberModifiers.Final | TypeMemberModifiers.Internal; Field callable = adaptor.AddField("$from", from); BooMethodBuilder constructor = adaptor.AddConstructor(); ParameterDeclaration param = constructor.AddParameter("from", from); constructor.Body.Add( CodeBuilder.CreateSuperConstructorInvocation(TypeSystemServices.ObjectType)); constructor.Body.Add( CodeBuilder.CreateAssignment( CodeBuilder.CreateReference(callable), CodeBuilder.CreateReference(param))); CallableSignature signature = to.GetSignature(); BooMethodBuilder invoke = adaptor.AddMethod("Invoke", signature.ReturnType); foreach (IParameter parameter in signature.Parameters) { invoke.AddParameter(parameter.Name, parameter.Type, parameter.IsByRef); } MethodInvocationExpression mie = CodeBuilder.CreateMethodInvocation( CodeBuilder.CreateReference(callable), GetInvokeMethod(from)); int fromParameterCount = from.GetSignature().Parameters.Length; for (int i = 0; i < fromParameterCount; ++i) { mie.Arguments.Add( CodeBuilder.CreateReference(invoke.Parameters[i])); } if (signature.ReturnType != TypeSystemServices.VoidType && from.GetSignature().ReturnType != TypeSystemServices.VoidType) { invoke.Body.Add(new ReturnStatement(mie)); } else { invoke.Body.Add(mie); } BooMethodBuilder adapt = adaptor.AddMethod("Adapt", to); adapt.Modifiers = TypeMemberModifiers.Static | TypeMemberModifiers.Public; param = adapt.AddParameter("from", from); adapt.Body.Add( new ReturnStatement( CodeBuilder.CreateConstructorInvocation( to.GetConstructors().First(), CodeBuilder.CreateConstructorInvocation( (IConstructor)constructor.Entity, CodeBuilder.CreateReference(param)), CodeBuilder.CreateAddressOfExpression(invoke.Entity)))); RegisterAdaptor(to, from, adaptor.ClassDefinition); return(adaptor.ClassDefinition); }
Field DeclareFieldInitializedFromConstructorParameter(BooClassBuilder type, BooMethodBuilder constructor, string parameterName, IType parameterType) { Field field = type.AddInternalField("$" + parameterName + _context.AllocIndex(), parameterType); InitializeFieldFromConstructorParameter(constructor, field, parameterName, parameterType); return field; }
private void CreateMoveNext() { BooMethodBuilder method = _enumerator.AddVirtualMethod("MoveNext", TypeSystemServices.BoolType); Expression moveNext = CodeBuilder.CreateMethodInvocation( CodeBuilder.CreateReference((InternalField)_enumeratorField.Entity), TypeSystemServices.Map(Methods.InstanceFunctionOf <IEnumerator, bool>(e => e.MoveNext))); Expression current = CodeBuilder.CreateMethodInvocation( CodeBuilder.CreateReference((InternalField)_enumeratorField.Entity), ((IProperty)GetMember(_sourceEnumeratorType, "Current", EntityType.Property)).GetGetMethod()); Statement filter = null; Statement stmt; Block outerBlock; Block innerBlock; if (null == _generator.Filter) { IfStatement istmt = new IfStatement(moveNext, new Block(), null); outerBlock = innerBlock = istmt.TrueBlock; stmt = istmt; } else { WhileStatement wstmt = new WhileStatement(moveNext); outerBlock = wstmt.Block; if (StatementModifierType.If == _generator.Filter.Type) { IfStatement ifstmt = new IfStatement(_generator.Filter.Condition, new Block(), null); innerBlock = ifstmt.TrueBlock; filter = ifstmt; } else { UnlessStatement ustmt = new UnlessStatement(_generator.Filter.Condition); innerBlock = ustmt.Block; filter = ustmt; } stmt = wstmt; } DeclarationCollection declarations = _generator.Declarations; if (declarations.Count > 1) { NormalizeIterationStatements.UnpackExpression(CodeBuilder, method.Method, outerBlock, current, declarations); foreach (Declaration declaration in declarations) { method.Locals.Add(((InternalLocal)declaration.Entity).Local); } } else { InternalLocal local = (InternalLocal)declarations[0].Entity; method.Locals.Add(local.Local); outerBlock.Add(CodeBuilder.CreateAssignment( CodeBuilder.CreateReference(local), current)); } if (null != filter) { outerBlock.Add(filter); } innerBlock.Add(CodeBuilder.CreateAssignment( CodeBuilder.CreateReference((InternalField)_current.Entity), _generator.Expression)); innerBlock.Add(new ReturnStatement(new BoolLiteralExpression(true))); method.Body.Add(stmt); method.Body.Add(new ReturnStatement(new BoolLiteralExpression(false))); }
void CreateGetEnumerator(Expression enumeratorExpression) { BooMethodBuilder method = GetGetEnumeratorBuilder(); method.Body.Add(new ReturnStatement(enumeratorExpression)); }
public BooMethodBuilder AddMethod(string name, IType returnType, TypeMemberModifiers modifiers) { BooMethodBuilder builder = new BooMethodBuilder(_codeBuilder, name, returnType, modifiers); _cd.Members.Add(builder.Method); return builder; }