protected override NameBinding ResolveBinding(string name) { NameBinding result = null; foreach (var poolBinding in this.Class.ImportedPoolBindings) { if (poolBinding.Value != null) { RTB.PoolVariableOrConstantBinding binding; poolBinding.Value.TryGetValue(name, out binding); if (binding != null) { if (result != null) { return(new ErrorBinding(name, CodeGenerationErrors.PoolVariableNotUnique)); } if (binding is RTB.PoolConstantBinding) { result = new PoolConstantBinding(name, poolBinding, (RTB.PoolConstantBinding)binding); } else { result = new PoolVariableBinding(name, poolBinding, (RTB.PoolVariableBinding)binding); } } } } return(result); // null means try outer scope. }
public override NameBinding GetBinding(string name) { // Try to see if we've already resolved this binding NameBinding result = base.GetBinding(name); if (result != null) { return(result); } // Try to resolve it ... result = this.ResolveBinding(name); if (result != null) { this.DefineBinding(result); // Cache it for next usage return(result); } // No luck ... try outer if (this.OuterScope != null) { return(this.OuterScope.GetBinding(name)); } else { return(null); } }
private Expression InlineIfTrueIfFalse(Compiler.SemanticNodes.BlockNode trueBlock, Compiler.SemanticNodes.BlockNode falseBlock) { NameBinding nilBinding = this.Context.GetBinding(SemanticConstants.Nil); Expression testExpression = Expression.Convert(this.Receiver, typeof(bool)); Expression trueExpression; if (trueBlock != null) { trueExpression = trueBlock.Accept(new InlineBlockVisitor(this)); } else { trueExpression = nilBinding.GenerateReadExpression(this); } Expression falseExpression; if (falseBlock != null) { falseExpression = falseBlock.Accept(new InlineBlockVisitor(this)); } else { falseExpression = nilBinding.GenerateReadExpression(this); } Expression result = Expression.Condition(testExpression, trueExpression, falseExpression, typeof(object)); this.SetResult(result); return(result); }
private Expression EncodeInlineWhile(BlockNode conditionBlock, BlockNode valueBlock, bool whileFalse) { NameBinding nilBinding = this.Context.GetBinding(SemanticConstants.Nil); Expression conditionExpression = Expression.Convert(conditionBlock.Accept(new InlineBlockVisitor(this)), typeof(bool)); // No, it's not an error ... if the <conditionExpression> evaluates to true, we terminate if (whileFalse) { conditionExpression = Expression.IsTrue(conditionExpression); } else { conditionExpression = Expression.IsFalse(conditionExpression); } LabelTarget exitLabel = Expression.Label(typeof(object)); GotoExpression exitLoop = Expression.Break(exitLabel, nilBinding.GenerateReadExpression(this)); Expression loop; if (valueBlock == null) { loop = Expression.IfThen(conditionExpression, exitLoop); } else { loop = Expression.IfThenElse(conditionExpression, exitLoop, valueBlock.Accept(new InlineBlockVisitor(this))); } return(Expression.Loop(loop, exitLabel)); }
public override Expression VisitBlock(Compiler.SemanticNodes.BlockNode node) { for (int i = 0; i < node.Arguments.Count; i++) { string name = node.Arguments[i].Token.Value; // This is used by the inlined blocks. // If already defined, do not define it twice ... because it's given externally. // See: DefineExternalArgument if (this.Context.LocalScope.GetBinding(name) != null) { continue; } this.Context.DefineArgument(name); } foreach (TemporaryVariableNode tmp in node.Temporaries) { this.Context.DefineTemporary(tmp.Token.Value); } List <Expression> expressions = new List <Expression>(); NameBinding nilBinding = this.Context.GetBinding(SemanticConstants.Nil); // On each execution init all temp-vars with nil foreach (TemporaryBinding tmp in this.Context.Temporaries) { expressions.Add(tmp.GenerateAssignExpression(nilBinding.GenerateReadExpression(this), this)); } StatementVisitor visitor = new StatementVisitor(this); if (node.Statements != null) { expressions.AddRange(node.Statements.Accept(visitor)); } if (expressions.Count == 0) { expressions.Add(nilBinding.GenerateReadExpression(this)); } #if DEBUG if (expressions.Count == 0) { throw new InternalCodeGenerationException("We did expect at least ONE expression"); } foreach (var expr in expressions) { if (expr.Type != typeof(object)) { throw new InternalCodeGenerationException(String.Format("Expression does not return object! \n{0}", expr)); } } #endif return(this.Context.GeneratePrologAndEpilogue(expressions)); }
public virtual void DefineBinding(NameBinding binding) { if (binding == null) { throw new ArgumentNullException(); } this.Bindings[binding.Name] = binding; }
private static string GetErrorDescription(NameBinding binding) { if (binding == null) { return(CodeGenerationErrors.UndefinedBinding); } return(String.Format("{0} {1}", binding.Name, (binding is IErrorBinding) ? ((IErrorBinding)binding).ErrorDescription : CodeGenerationErrors.UndefinedBinding)); }
private Expression InlineOr(Compiler.SemanticNodes.BlockNode block) { NameBinding trueBinding = this.Context.GetBinding(SemanticConstants.True); Expression testExpression = Expression.Convert(this.Receiver, typeof(bool)); Expression blockExpression = block.Accept(new InlineBlockVisitor(this)); Expression result = Expression.Condition(testExpression, trueBinding.GenerateReadExpression(this), blockExpression, typeof(object)); this.SetResult(result); return(result); }
internal NameBinding GetLocalVariable(string name) { NameBinding result = this.LocalScope.GetBinding(name); if (result != null) { return(result); } return(new ErrorBinding(name)); }
public override Expression VisitVariableReferencele(VariableReferenceleNode node) { NameBinding target = this.Context.GetBinding(node.Token.Value); if (target.IsErrorBinding) { throw new BindingCodeGeneraionException(target, node); } this.IsSuperSend = (node.Token.Value == SemanticConstants.Super); this.IsConstant = target.IsConstantValueBinding; return(target.GenerateReadExpression(this)); }
protected override List <Expression> GenerateExpressions(InitializerNode node, out StatementVisitor visitor) { List <Expression> expressions = base.GenerateExpressions(node, out visitor); if (expressions.Count == 0) { NameBinding binding = this.Context.GetBinding(SemanticConstants.Self); if (binding.IsErrorBinding) { binding = this.Context.GetBinding(SemanticConstants.Nil); } expressions.Add(binding.GenerateReadExpression(this)); } return(expressions); }
protected override List <Expression> GenerateExpressions(MethodNode node, out StatementVisitor visitor) { List <Expression> expressions = new List <Expression>(); if (node.Primitive != null) { expressions.AddRange(node.Primitive.Accept(new PrimitiveCallVisitor(this, (node.Statements != null)))); } expressions.AddRange(base.GenerateExpressions(node, out visitor)); if ((node.Primitive == null) && ((expressions.Count == 0) || !visitor.HasReturned)) { // If no explicit return, a method must return self. NameBinding binding = this.Context.GetBinding(SemanticConstants.Self); expressions.Add(binding.GenerateReadExpression(this)); } return(expressions); }
public override Expression VisitAssignment(AssignmentNode node) { NameBinding target = this.Context.GetBinding(node.Target.Token.Value); if (target.IsErrorBinding) { throw new BindingCodeGeneraionException(target, node); } if (!(target is IAssignableBinding)) { throw new BindingCodeGeneraionException(CodeGenerationErrors.AssigningToConstant, node); } ExpressionVisitor visitor = new ExpressionVisitor(this); Expression value = node.Expression.Accept(visitor); this.IsConstant = visitor.IsConstant; return(((IAssignableBinding)target).GenerateAssignExpression(value, this)); }
protected override NameBinding ResolveBinding(string name) { NameBinding result = null; RTB.PoolVariableOrConstantBinding binding; this.Pool.TryGetValue(name, out binding); if (binding != null) { RTB.PoolBinding poolBinding = this.Pool.Runtime.GlobalScope.GetPoolBinding(this.Pool.Name); System.Diagnostics.Debug.Assert(poolBinding != null, String.Format("Could not find pool binding named {0}.", this.Pool.Name.Value)); if (binding is RTB.PoolConstantBinding) { result = new PoolConstantBinding(name, poolBinding, (RTB.PoolConstantBinding)binding); } else { result = new PoolVariableBinding(name, poolBinding, (RTB.PoolVariableBinding)binding); } } return(result); // null means try outer scope. }
internal override NameBinding GetBinding(string name) { NameBinding result = this.ReservedScope.GetBinding(name); if (result != null) { return(result); } result = this.LocalScope.GetBinding(name); if (result != null) { return(result); } result = this.GlobalScope.GetBinding(name); if (result != null) { return(result); } return(new ErrorBinding(name)); }
public virtual Expression VisitNameBindingCore(NameBinding nameBinding){ if (nameBinding == null) return null; MemberBinding mb = this.GetMemberBinding(nameBinding); Expression cb = this.GetContextBinding(nameBinding); if (mb == null){ if (cb != null){ nameBinding.BoundMember = cb; return cb; } return null; } bool isQueryBinding = (mb.BoundMember != null && mb.BoundMember.DeclaringType is QueryScope); if (cb != null){ if (isQueryBinding) return cb; this.HandleError(nameBinding, Error.QueryAmbiguousContextName, nameBinding.Identifier.Name); } if (isQueryBinding) return nameBinding; return mb; }
public virtual Expression GetContextBinding(NameBinding nameBinding){ if (nameBinding == null) return null; bool savedCR = this.hasContextReference; QueryContext qc = new QueryContext(); qc.SourceContext = nameBinding.SourceContext; for (ContextScope scope = this.contextScope; scope != null; scope = scope.Previous){ qc.Type = scope.Type; qc.Scope = scope; QualifiedIdentifier qi = new QualifiedIdentifier(qc, nameBinding.Identifier); Expression result = this.VisitQualifiedIdentifier(qi); if (result != null && result != qi){ result.SourceContext = nameBinding.SourceContext; return result; } } this.hasContextReference = savedCR; return null; }
public virtual void VisitNameBinding(NameBinding nameBinding) { }
private static void toDoc(Doc doc, NameBinding nameBinding, JsonDataMap jsonMap, ref string field, bool fromUI) { var amorph = doc as IAmorphousData; foreach (var mfld in jsonMap) { field = mfld.Key; var fv = mfld.Value; //Multitargeting for deserilization to TypedDoc from JSON Schema.FieldDef def; if (nameBinding.BindBy == NameBinding.By.CodeName) { def = doc.Schema[field]; } else { def = doc.Schema.TryFindFieldByTargetedBackendName(nameBinding.TargetName, field);//what about case sensitive json name? } //No such field exists in a typed doc, try to put in amorphous data if (def == null) { if (amorph != null) { if (amorph.AmorphousDataEnabled) { amorph.AmorphousData[mfld.Key] = fv; } } continue; } if (fromUI && def.NonUI) { continue; //skip NonUI fields } if (fv == null) { doc.SetFieldValue(def, null); continue; } //fv is Never null here var wasset = setOneField(doc, def, fv, fromUI, nameBinding); //<------------------- field assignment //try to put in amorphous data if could not be set in a field if (!wasset && amorph != null) { if (amorph.AmorphousDataEnabled) { amorph.AmorphousData[mfld.Key] = fv; } } }//foreach field in jsonMap //process FORM var form = doc as Form; if (form != null) { form.FormMode = jsonMap[Form.JSON_MODE_PROPERTY].AsEnum <FormMode>(FormMode.Unspecified); form.CSRFToken = jsonMap[Form.JSON_CSRF_PROPERTY].AsString(); var roundtrip = jsonMap[Form.JSON_ROUNDTRIP_PROPERTY].AsString(); if (roundtrip.IsNotNullOrWhiteSpace()) { form.SetRoundtripBagFromJSONString(roundtrip); } } if (amorph != null && amorph.AmorphousDataEnabled) { amorph.AfterLoad("json"); } }
public virtual Expression VisitNameBinding(NameBinding nameBinding){ return nameBinding; }
public override Expression VisitNameBinding(NameBinding nameBinding){ if (nameBinding == null) return null; nameBinding.BoundMember = this.VisitExpression(nameBinding.BoundMember); int n = nameBinding.BoundMembers == null ? 0 : nameBinding.BoundMembers.Count; for (int i = 0; i < n; i++) { //^ assert nameBinding.BoundMembers != null; nameBinding.BoundMembers[i] = this.VisitMemberReference(nameBinding.BoundMembers[i]); } return nameBinding; }
public virtual Expression OnInvalidNameBinding(NameBinding nb, NameBinding nameBinding){ return nameBinding; }
public override Expression VisitNameBinding(NameBinding nb) { base.VisitNameBinding(nb); return (Expression) this.Compose(nb, this.contextComposer); }
public override Expression VisitNameBinding(NameBinding nb) { base.VisitNameBinding(nb); return((Expression)this.Compose(nb, this.contextComposer)); }
public BindingCodeGeneraionException(NameBinding binding, SemanticNode node) : this(BindingCodeGeneraionException.GetErrorDescription(binding), node) { }
private static void toRow(Row row, NameBinding nameBinding, JSONDataMap jsonMap, ref string field, bool fromUI) { var amorph = row as IAmorphousData; foreach (var mfld in jsonMap) { field = mfld.Key; var fv = mfld.Value; //20170420 DKh+Ogee multitargeting for deserilization to ROW from JSON Schema.FieldDef rfd; if (nameBinding.BindBy == NameBinding.By.CodeName) { rfd = row.Schema[field]; } else { rfd = row.Schema.TryFindFieldByTargetedBackendName(nameBinding.TargetName, field); //what about case sensitive json name? } if (rfd == null) { if (amorph != null) { if (amorph.AmorphousDataEnabled) { amorph.AmorphousData[mfld.Key] = fv; } } continue; } if (fromUI && rfd.NonUI) { continue; //skip NonUI fields } if (fv == null) { row.SetFieldValue(rfd, null); } else if (fv is JSONDataMap) { if (typeof(TypedRow).IsAssignableFrom(rfd.Type)) { row.SetFieldValue(rfd, ToRow(rfd.Type, (JSONDataMap)fv, fromUI, nameBinding)); } else { row.SetFieldValue(rfd, fv); //try to set row's field to MAP directly } } else if (rfd.NonNullableType == typeof(TimeSpan) && (fv is ulong || fv is long || fv is int || fv is uint)) { var lt = Convert.ToInt64(fv); row.SetFieldValue(rfd, TimeSpan.FromTicks(lt)); } else if (fv is int || fv is long || fv is ulong || fv is double || fv is bool) { row.SetFieldValue(rfd, fv); } else if (fv is byte[] && rfd.Type == typeof(byte[])) //optimization byte array assignment without copies { var passed = (byte[])fv; var arr = new byte[passed.Length]; Array.Copy(passed, arr, passed.Length); row.SetFieldValue(rfd, arr); } else if (fv is JSONDataArray || fv.GetType().IsArray) { JSONDataArray arr; if (fv is JSONDataArray) { arr = (JSONDataArray)fv; } else { arr = new JSONDataArray(((Array)fv).Length); foreach (var elm in (System.Collections.IEnumerable)fv) { arr.Add(elm); } } if (rfd.Type.IsArray) { var raet = rfd.Type.GetElementType(); //row array element type if (typeof(TypedRow).IsAssignableFrom(raet)) { var narr = Array.CreateInstance(raet, arr.Count); for (var i = 0; i < narr.Length; i++) { narr.SetValue(ToRow(raet, arr[i] as JSONDataMap, fromUI, nameBinding), i); } row.SetFieldValue(rfd, narr); } //else primitives else { var narr = Array.CreateInstance(raet, arr.Count); for (var i = 0; i < narr.Length; i++) { if (arr[i] != null) { narr.SetValue(StringValueConversion.AsType(arr[i].ToString(), raet, false), i); } } row.SetFieldValue(rfd, narr); } } else if (rfd.Type.IsGenericType && rfd.Type.GetGenericTypeDefinition() == typeof(List <>)) //List { var gat = rfd.Type.GetGenericArguments()[0]; var lst = Activator.CreateInstance(rfd.Type) as System.Collections.IList; if (typeof(TypedRow).IsAssignableFrom(gat)) { for (var i = 0; i < arr.Count; i++) { if (arr[i] is JSONDataMap) { lst.Add(ToRow(gat, arr[i] as JSONDataMap, fromUI, nameBinding)); } else { lst.Add(null); } } } else if (gat == typeof(object)) { for (var i = 0; i < arr.Count; i++) { lst.Add(arr[i]); } } else if (gat == typeof(string)) { for (var i = 0; i < arr.Count; i++) { if (arr[i] != null) { lst.Add(arr[i].ToString()); } else { lst.Add(null); } } } else if (gat.IsPrimitive || gat == typeof(NFX.DataAccess.Distributed.GDID) || gat == typeof(Guid) || gat == typeof(DateTime)) { for (var i = 0; i < arr.Count; i++) { if (arr[i] != null) { lst.Add(StringValueConversion.AsType(arr[i].ToString(), gat, false)); } } } else if (gat.IsGenericType && gat.GetGenericTypeDefinition() == typeof(Nullable <>)) { var nt = gat.GetGenericArguments()[0]; if (nt.IsPrimitive || nt == typeof(NFX.DataAccess.Distributed.GDID) || nt == typeof(Guid) || nt == typeof(DateTime)) { for (var i = 0; i < arr.Count; i++) { if (arr[i] != null) { lst.Add(StringValueConversion.AsType(arr[i].ToString(), gat, false)); } else { lst.Add(null); } } } } row.SetFieldValue(rfd, lst); } } else { //Try to get String containing JSON if (fv is string) { var sfv = (string)fv; if (rfd.Type == typeof(string)) { row.SetFieldValue(rfd, sfv); continue; } if (typeof(TypedRow).IsAssignableFrom(rfd.Type)) { if (sfv.IsNotNullOrWhiteSpace()) { row.SetFieldValue(rfd, ToRow(rfd.Type, (JSONDataMap)deserializeObject(read(sfv, true)), fromUI, nameBinding)); } continue; } if (typeof(IJSONDataObject).IsAssignableFrom(rfd.Type)) { if (sfv.IsNotNullOrWhiteSpace()) { row.SetFieldValue(rfd, deserializeObject(read(sfv, true))); //try to set row's field to MAP directly } continue; } } row.SetFieldValue(rfd, StringValueConversion.AsType(fv.ToString(), rfd.Type, false)); //<--Type conversion } } //foreach //20140914 DKh var form = row as FormModel; if (form != null) { form.FormMode = jsonMap[FormModel.JSON_MODE_PROPERTY].AsEnum <FormMode>(FormMode.Unspecified); form.CSRFToken = jsonMap[FormModel.JSON_CSRF_PROPERTY].AsString(); var roundtrip = jsonMap[FormModel.JSON_ROUNDTRIP_PROPERTY].AsString(); if (roundtrip.IsNotNullOrWhiteSpace()) { form.SetRoundtripBagFromJSONString(roundtrip); } } if (amorph != null && amorph.AmorphousDataEnabled) { amorph.AfterLoad("json"); } }
}//setOneField //Returns non null on success; may return null for collection sub-element in which case null=null and does not indicate failure private static object cast(object v, Type toType, bool fromUI, NameBinding nameBinding) { //used only for collections inner calls if (v == null) { return(null); } //object goes as is if (toType == typeof(object)) { return(v); } //IJSONDataObject if (toType == typeof(IJsonDataObject)) { if (v is IJsonDataObject) { return(v); //goes as is } if (v is string s) //string containing embedded JSON { var jo = s.JsonToDataObject(); return(jo); } } //IJSONDataMap if (toType == typeof(JsonDataMap)) { if (v is JsonDataMap) { return(v); //goes as is } if (v is string s) //string containing embedded JSON { var jo = s.JsonToDataObject() as JsonDataMap; return(jo); } } //IJSONDataArray if (toType == typeof(JsonDataArray)) { if (v is JsonDataArray) { return(v); //goes as is } if (v is string s) //string containing embedded JSON { var jo = s.JsonToDataObject() as JsonDataArray; return(jo); } } var nntp = toType; if (toType.IsGenericType && nntp.GetGenericTypeDefinition() == typeof(Nullable <>)) { nntp = toType.GetGenericArguments()[0]; } //Custom JSON Readable (including config) if (typeof(IJsonReadable).IsAssignableFrom(nntp) || typeof(IConfigSectionNode).IsAssignableFrom(nntp)) { var toAllocate = nntp; //Configuration requires special handling because nodes do not exist as independent entities and there //is master/detail relationship between them if (toAllocate == typeof(Configuration) || toAllocate == typeof(ConfigSectionNode) || toAllocate == typeof(IConfigSectionNode)) { toAllocate = typeof(MemoryConfiguration); } var newval = SerializationUtils.MakeNewObjectInstance(toAllocate) as IJsonReadable; var got = newval.ReadAsJson(v, fromUI, nameBinding);//this me re-allocate the result based of newval if (!got.match) { return(null); } if (typeof(IConfigSectionNode).IsAssignableFrom(nntp)) { return((got.self as Configuration)?.Root); } return(got.self); } //byte[] direct assignment w/o copies if (nntp == typeof(byte[]) && v is byte[] passed) { return(passed); } //field def = [] if (toType.IsArray) { var fvseq = v as IEnumerable <object>; if (fvseq == null) { return(null); //can not set non enumerable into array } var arr = fvseq.Select(e => cast(e, toType.GetElementType(), fromUI, nameBinding)).ToArray(); var newval = Array.CreateInstance(toType.GetElementType(), arr.Length); for (var i = 0; i < newval.Length; i++) { newval.SetValue(arr[i], i); } return(newval); } //field def = List<t> if (toType.IsGenericType && toType.GetGenericTypeDefinition() == typeof(List <>)) { var fvseq = v as IEnumerable <object>; if (fvseq == null) { return(false); //can not set non enumerable into List<t> } var arr = fvseq.Select(e => cast(e, toType.GetGenericArguments()[0], fromUI, nameBinding)).ToArray(); var newval = SerializationUtils.MakeNewObjectInstance(toType) as System.Collections.IList; for (var i = 0; i < arr.Length; i++) { newval.Add(arr[i]); } return(newval); } //last resort try { return(StringValueConversion.AsType(v.ToString(), toType, false)); } catch { return(null);//the value could not be converted, and is going to go into amorphous bag if it is enabled } }
private static bool setOneField(Doc doc, Schema.FieldDef def, object fv, bool fromUI, NameBinding nameBinding) { var converted = cast(fv, def.Type, fromUI, nameBinding); ////Console.WriteLine($"{def.Name} = {converted} ({(converted!=null ? converted.GetType().Name : "null")})"); if (converted != null) { doc.SetFieldValue(def, converted); return(true); } return(false); }//setOneField
public override Expression VisitNameBinding(NameBinding nameBinding){ if (nameBinding == null) return null; Expression result = this.VisitNameBindingCore(nameBinding); if (result == null) return nameBinding; MemberBinding mb = result as MemberBinding; if (mb == null) return result; Property p = mb.BoundMember as Property; if (p != null){ Method getter = p.Getter; if (getter == null) return mb; mb.BoundMember = getter; MethodCall mc = new MethodCall(mb, new ExpressionList()); if (!(mb.TargetObject is Base) && getter.IsVirtualAndNotDeclaredInStruct) mc.NodeType = NodeType.Callvirt; mc.SourceContext = nameBinding.SourceContext; mc.Type = p.Type; return mc; } Field f = mb.BoundMember as Field; if (f != null){ if (f != null && f.IsLiteral){ Literal defaultValue = f.DefaultValue; if (defaultValue == null) defaultValue = f.DefaultValue = this.EvaluateAsLiteral(f.Initializer); if (defaultValue != null){ Literal lit = (Literal)defaultValue.Clone(); lit.SourceContext = nameBinding.SourceContext; lit = this.CoerceLiteral(mb, f, lit); if (lit != null) return lit; } } } return mb; }
public override Expression VisitNameBinding(NameBinding nameBinding) { throw new ApplicationException("unimplemented"); }
public virtual MemberBinding GetMemberBinding(NameBinding nameBinding){ Member target = null; TypeNode targetType = SystemTypes.Object; Expression thisob = null; if (nameBinding == null) goto done; MemberList members = nameBinding.BoundMembers; for (int i = 0, n = members == null ? 0 : members.Count; i < n; i++){ target = members[i]; switch(target.NodeType){ case NodeType.Field: Field f = (Field)target; thisob = this.GetObject(nameBinding); if (f.IsStatic && (thisob is ImplicitThis || (thisob != null && thisob.Type == SystemTypes.Type && thisob is Literal))) thisob = null; targetType = f.Type; if (targetType == null && f is ParameterField) targetType = f.Type = ((ParameterField)f).Parameter.Type; goto done; case NodeType.Property: Property p = (Property)target; if (p.ImplementedTypeExpressions != null && p.ImplementedTypeExpressions.Count > 0) { target = null; continue; } Method g = p.Getter; Method s = p.Setter; if (g != null && g.Parameters != null && g.Parameters.Count != 0) continue; if (s != null && (s.Parameters == null || s.Parameters.Count != 1)) continue; thisob = this.GetObject(nameBinding); if (p.IsStatic && (thisob is ImplicitThis || (thisob != null && thisob.Type == SystemTypes.Type && thisob is Literal))) thisob = null; targetType = p.Type; goto done; case NodeType.Method: Method m = (Method)target; if (m.ImplementedTypeExpressions != null && m.ImplementedTypeExpressions.Count > 0) { target = null; continue; } thisob = this.GetObject(nameBinding); targetType = SystemTypes.Delegate; goto done; case NodeType.Event: //Can get here if there is a forward reference to a field backed event targetType = target.DeclaringType; if (targetType == null) break; target = this.GetTypeView(targetType).GetField(target.Name); if (target != null) goto case NodeType.Field; target = members[i]; targetType = ((Event)target).HandlerType; if (!target.IsStatic) thisob = this.GetObject(nameBinding); break; } } if (!(target is Event)) target = null; done: if (target == null) return null; MemberBinding result = new MemberBinding(thisob, target, nameBinding); result.Type = targetType; result.SourceContext = nameBinding.SourceContext; nameBinding.BoundMember = result; return result; }
public virtual Differences VisitNameBinding(NameBinding nameBinding1, NameBinding nameBinding2){ Differences differences = new Differences(nameBinding1, nameBinding2); if (nameBinding1 == null || nameBinding2 == null){ if (nameBinding1 != nameBinding2) differences.NumberOfDifferences++; else differences.NumberOfSimilarities++; return differences; } NameBinding changes = (NameBinding)nameBinding2.Clone(); NameBinding deletions = (NameBinding)nameBinding2.Clone(); NameBinding insertions = (NameBinding)nameBinding2.Clone(); MemberList memChanges, memDeletions, memInsertions; Differences diff = this.VisitMemberList(nameBinding1.BoundMembers, nameBinding2.BoundMembers, out memChanges, out memDeletions, out memInsertions); if (diff == null){Debug.Assert(false); return differences;} changes.BoundMembers = memChanges; deletions.BoundMembers = memDeletions; insertions.BoundMembers = memInsertions; differences.NumberOfDifferences += diff.NumberOfDifferences; differences.NumberOfSimilarities += diff.NumberOfSimilarities; diff = this.VisitIdentifier(nameBinding1.Identifier, nameBinding2.Identifier); if (diff == null){Debug.Assert(false); return differences;} changes.Identifier = diff.Changes as Identifier; deletions.Identifier = diff.Deletions as Identifier; insertions.Identifier = diff.Insertions as Identifier; Debug.Assert(diff.Changes == changes.Identifier && diff.Deletions == deletions.Identifier && diff.Insertions == insertions.Identifier); differences.NumberOfDifferences += diff.NumberOfDifferences; differences.NumberOfSimilarities += diff.NumberOfSimilarities; if (differences.NumberOfDifferences == 0){ differences.Changes = null; differences.Deletions = null; differences.Insertions = null; }else{ differences.Changes = changes; differences.Deletions = deletions; differences.Insertions = insertions; } return differences; }
public override Expression VisitNameBinding(NameBinding nameBinding) { if (nameBinding == null) return null; this.HandleError(nameBinding, Error.IdentifierNotFound, nameBinding.Identifier.ToString()); return null; }
public virtual bool BoundNameHides(NameBinding nb, TypeNode t) { if (nb == null) return false; for (int i = 0, n = nb.BoundMembers == null ? 0 : nb.BoundMembers.Count; i < n; i++) { Member mem = nb.BoundMembers[i]; if (mem == null) continue; Property prop = mem as Property; if (prop != null) return TypeNode.StripModifiers(prop.Type) != t; Field f = mem as Field; if (f != null) return TypeNode.StripModifiers(f.Type) != t; } return false; }
/// <summary> /// Visits the Primitive Call node. /// </summary> /// <param name="node">The node to visit.</param> /// <remarks> /// This is the place where primitive calls are encoded to expressions and where most of the interop to the .Net framework happens. /// </remarks> public override List <Expression> VisitPrimitiveCall(Compiler.SemanticNodes.PrimitiveCallNode node) { // Large case with the API conventions we support; // Each generates an Expression to perform the primitive call. Expression primitiveCall; try { primitiveCall = this.GeneratePrimitiveExpression(node); } catch (CodeGenerationException ex) { ex.SetErrorLocation(node); throw; } // We need to handle void returns, because Smalltalk always needs a valid receiver. NameBinding selfBinding = this.MethodVisitor.Context.GetBinding(SemanticConstants.Self); if (primitiveCall.Type == typeof(void)) { primitiveCall = Expression.Block(primitiveCall, selfBinding.GenerateReadExpression(this)); } else if (primitiveCall.Type != typeof(object)) { primitiveCall = Expression.Convert(primitiveCall, typeof(object)); } // A successful primitive call must return directly without executing any other statements. primitiveCall = this.Context.Return(primitiveCall); List <Expression> result = new List <Expression>(); if (this.HasFallbackCode) { // This is the case, where some Smalltalk fall-back code follows the primitive call. // In this case, we encapsulate the primitive call in a try-catch block, similar to: // object _exception; // optional ... defined by the Smalltalk method // try // { // return (object) primitiveCall(); // } catch (Exception exception) { // _exception = exception; // optional ... only if "_exception" variable is declared. // }; Expression handler; // This is the special hardcoded temp variable we are looking for. NameBinding exceptionVariable = this.MethodVisitor.GetLocalVariable("_exception"); ParameterExpression expetionParam = Expression.Parameter(typeof(Exception), "exception"); if (!exceptionVariable.IsErrorBinding && (exceptionVariable is IAssignableBinding)) { // Case of handler block that sets the "_exception" temporary variable and has "self" as the last statement. handler = Expression.Block( ((IAssignableBinding)exceptionVariable).GenerateAssignExpression(expetionParam, this), Expression.Convert(selfBinding.GenerateReadExpression(this), typeof(object))); } else { // Case of handler block that has "self" as the one and only statement handler = Expression.Convert(selfBinding.GenerateReadExpression(this), typeof(object)); } // Create the try/catch block. result.Add(Expression.TryCatch(primitiveCall, Expression.Catch(typeof(BlockResult), Expression.Rethrow(typeof(object))), Expression.Catch(expetionParam, handler))); } else { // This is the case, where none Smalltalk fall-back code follows the primitive call. // The API call is called directly without any encapsulation in a try-catch block, similar to: // return (object) primitiveCall(); // If it fails, it fails and an exception is thrown. The sender of the Smalltalk method // is responsible for handling exceptions manually. result.Add(primitiveCall); } return(result); }
private Expression InlineToByDo(Expression start, Expression stop, Expression step, Compiler.SemanticNodes.BlockNode block) { /// to:by:do: /* C# semantics of the inlining * if ((start is int) && (stop is int) && (step is int)) * { * int iStart, iStop, iStep; * try * { * iStart = checked((int)start); * iStop = checked((int)stop); * iStep = checked((int)step); * // This is to ensure the calculation below do not fail running unchecked * int na = checked(iStart + iStep); * na = checked(iStop + iStep); * } * catch (OverflowException) * { * goto Int32Overwlow; * } * * if (iStep == 0) * throw new ArgumentOutOfRangeException(); * * if (iStep > 0) * { * do * { * if (iStart > iStop) * goto Exit; * block(iStart); * iStart = iStart + iStep; * } while (true); * } * else * { * do * { * if (iStop > iStart) * goto Exit; * block(iStart); * iStart = iStart + iStep; * } while (true); * } * } * Int32Overwlow: * // We could implement BigInteger optimization here, but too much work and probably not much to gain * // Fallback to dynamic invocation * dynamic dStart = start; * dynamic dStep = step; * if (dStep == 0) * throw new ArgumentOutOfRangeException(); * * if (dStep > 0) * { * do * { * if (dStart > stop) * goto Exit; * block(dStart); * dStart = dStart + step; * } while (true); * } * else * { * do * { * if (stop > dStart) * goto Exit; * block(dStart); * dStart = dStart + step; * } while (true); * } * Exit: */ NameBinding nilBinding = this.Context.GetBinding(SemanticConstants.Nil); LabelTarget exitLabel = Expression.Label(typeof(void)); LabelTarget overflowLabel = Expression.Label(typeof(void)); ParameterExpression iStart = Expression.Variable(typeof(int), "iStart"); ParameterExpression iStop = Expression.Variable(typeof(int), "iStop"); ParameterExpression iStep = Expression.Variable(typeof(int), "iStep"); ParameterExpression iNA = Expression.Variable(typeof(int), "iNA"); InlineBlockVisitor visitor = new InlineBlockVisitor(this); if (block.Arguments.Count > 0) { visitor.DefineExternalArgument(block.Arguments[0].Token.Value, Expression.Convert(iStart, typeof(object))); } Expression integerOperation = block.Accept(visitor); Expression integerTest = Expression.AndAlso(Expression.AndAlso( Expression.TypeIs(start, typeof(int)), Expression.TypeIs(stop, typeof(int))), Expression.TypeIs(step, typeof(int))); Expression integerBlock = Expression.Block( Expression.TryCatch( Expression.Block( Expression.Assign(iStart, Expression.ConvertChecked(start, typeof(int))), Expression.Assign(iStop, Expression.ConvertChecked(stop, typeof(int))), Expression.Assign(iStep, Expression.ConvertChecked(step, typeof(int))), Expression.Assign(iNA, Expression.AddChecked(iStart, iStep)), Expression.Assign(iNA, Expression.AddChecked(iStop, iStep))), Expression.Catch(typeof(OverflowException), Expression.Goto(overflowLabel, typeof(int))), Expression.Catch(typeof(InvalidCastException), Expression.Goto(overflowLabel, typeof(int)))), Expression.IfThen( Expression.Equal(iStep, Expression.Constant(0)), Expression.Throw(Expression.New(typeof(ArgumentOutOfRangeException)), typeof(object))), Expression.IfThenElse( Expression.GreaterThan(iStep, Expression.Constant(0)), Expression.Loop( Expression.IfThenElse( Expression.GreaterThan(iStart, iStop), Expression.Break(exitLabel, nilBinding.GenerateReadExpression(this)), Expression.Block( integerOperation, Expression.AddAssign(iStart, iStep)))), Expression.Loop( Expression.IfThenElse( Expression.GreaterThan(iStop, iStart), Expression.Break(exitLabel, nilBinding.GenerateReadExpression(this)), Expression.Block( integerOperation, Expression.AddAssign(iStart, iStep)))))); ParameterExpression dStart = Expression.Variable(typeof(object), "dStart"); ParameterExpression dStep = Expression.Variable(typeof(object), "dStep"); visitor = new InlineBlockVisitor(this); if (block.Arguments.Count > 0) { visitor.DefineExternalArgument(block.Arguments[0].Token.Value, dStart); } Expression dynamicOperation = block.Accept(visitor); Expression dynamicBlock = Expression.Block( Expression.Assign(dStart, start), Expression.Assign(dStep, Expression.Convert(step, typeof(object))), Expression.IfThen( Expression.IsTrue(Expression.Convert(this.Context.CompileDynamicCall(this, "=", dStep, PreboxedConstants.Int32_00000000_Expression), typeof(bool))), Expression.Throw(Expression.New(typeof(ArgumentOutOfRangeException)), typeof(object))), Expression.IfThenElse( Expression.IsTrue(Expression.Convert(this.Context.CompileDynamicCall(this, ">", dStep, PreboxedConstants.Int32_00000000_Expression), typeof(bool))), Expression.Loop( Expression.IfThenElse( Expression.IsTrue(Expression.Convert(this.Context.CompileDynamicCall(this, ">", dStart, stop), typeof(bool))), Expression.Break(exitLabel, nilBinding.GenerateReadExpression(this)), Expression.Block( dynamicOperation, Expression.Assign(dStart, this.Context.CompileDynamicCall(this, "+", dStart, dStep))))), Expression.Loop( Expression.IfThenElse( Expression.IsTrue(Expression.Convert(this.Context.CompileDynamicCall(this, ">", stop, dStart), typeof(bool))), Expression.Break(exitLabel, nilBinding.GenerateReadExpression(this)), Expression.Block( dynamicOperation, Expression.Assign(dStart, this.Context.CompileDynamicCall(this, "+", dStart, dStep))))))); return(Expression.Block( new ParameterExpression[] { iStart, iStop, iStep, iNA, dStart, dStep }, integerBlock, Expression.Label(overflowLabel), dynamicBlock, Expression.Label(exitLabel), nilBinding.GenerateReadExpression(this))); }
protected virtual MemberList GetMembers(int line, int col, NameBinding nameBinding, Scope scope, bool doingCompletion) { if (nameBinding == null) return null; if (nameBinding.BoundMembers != null && !doingCompletion) return this.FilterOutIncassessibleMembers(nameBinding.BoundMembers, scope); if (scope != null) return this.languageService.GetVisibleNames(scope); return null; }
public virtual Expression VisitNameBinding(NameBinding nameBinding1, NameBinding nameBinding2) { return nameBinding1; }
public override Expression VisitIdentifier(Identifier identifier){ if (identifier == null) return null; AliasDefinition aliasDef = null; TypeNode t = null; TypeNode inaccessibleType = null; Namespace nspace = null; MemberList members = null; MemberList nameBindingMembers = null; int lexLevel = 0; Identifier prefix = identifier.Prefix; if (prefix != null) { Node n = this.LookupTypeOrNamespace(prefix, identifier, false, 0); if (this.identifierInfos != null) aliasDef = this.LookupAlias(prefix); t = n as TypeNode; if (t != null) goto returnT; if (n == null){ aliasDef = this.LookupAlias(prefix); if (aliasDef != null && aliasDef.AliasedType != null) { this.HandleError(identifier.Prefix, Error.TypeAliasUsedAsNamespacePrefix, aliasDef.Alias.Name); this.HandleError(aliasDef, Error.RelatedErrorLocation); return null; } n = identifier; }else if (this.identifierInfos != null) aliasDef = this.LookupAlias(prefix); Debug.Assert(n is Identifier); nspace = new Namespace((Identifier)n); goto returnNspace; } if (identifier.UniqueIdKey == Identifier.Empty.UniqueIdKey) { this.AddNodePositionAndInfo(identifier, identifier, IdentifierContexts.AllContext); return identifier; } Scope scope = this.scope; while (scope != null){ NamespaceScope nsScope = scope as NamespaceScope; if (nsScope != null){ Node node = this.LookupTypeOrNamespace(null, identifier, false, nsScope, 0); t = node as TypeNode; if (t != null) goto returnT; if (node != null){ aliasDef = node as AliasDefinition; if (aliasDef != null) nspace = new Namespace(identifier); else{ Debug.Assert(node is Identifier); nspace = new Namespace((Identifier)node); } goto returnNspace; } MemberList anonymousMembers = this.LookupAnonymousMembers(identifier, nsScope); if (anonymousMembers != null && anonymousMembers.Count > 0){ nameBindingMembers = anonymousMembers; goto done; } }else{ TypeScope tScope = scope as TypeScope; if (tScope != null){ TypeNode type = tScope.Type; TypeNodeList tparams = tScope.TemplateParameters; for (int i = 0, n = tparams == null ? 0 : tparams.Count; i < n; i++){ t = tparams[i]; if (t == null) continue; if (t.Name.UniqueIdKey == identifier.UniqueIdKey) goto returnT; } while (type != null){ members = this.GetTypeView(type).GetMembersNamed(identifier); if (nameBindingMembers == null || nameBindingMembers.Count == 0) nameBindingMembers = members; for (int i = 0, n = members == null ? 0 : members.Count; i < n; i++){ Member mem = members[i]; TypeNode dummy = this.currentType; if (Checker.NotAccessible(mem, ref dummy, this.currentModule, this.currentType, this.TypeViewer)){ if (mem is TypeNode) inaccessibleType = (TypeNode)mem; continue; } t = mem as TypeNode; if (t != null){ if (this.TypeIsVisible(t)) goto returnT; inaccessibleType = t; } goto done; } Expression pseudoMember = this.BindPseudoMember(type, identifier); if (pseudoMember != null) return pseudoMember; Class c = type as Class; if (c != null && c.BaseClass == null && c.DeclaringModule == this.currentModule) this.VisitBaseClassReference(c); if (type == SystemTypes.Object) break; type = type.BaseType; } }else{ members = scope.GetMembersNamed(identifier); if (nameBindingMembers == null || nameBindingMembers.Count == 0) nameBindingMembers = members; if (members != null && members.Count > 0){ t = members[0] as TypeNode; if (t != null && members.Count == 1) goto returnT; goto done; } TypeNodeList tparams = scope.TemplateParameters; for (int i = 0, n = tparams == null ? 0 : tparams.Count; i < n; i++){ t = tparams[i]; if (t.Name.UniqueIdKey == identifier.UniqueIdKey) goto returnT; } } } scope = scope.OuterScope; lexLevel++; } returnT: if (t != null){ this.AddNodePositionAndInfo(identifier, t, IdentifierContexts.AllContext); return new Literal(t, SystemTypes.Type, identifier.SourceContext); } returnNspace: if (nspace != null){ if (identifier == nspace.Name && aliasDef != null){ this.AddNodePositionAndInfo(identifier, aliasDef, IdentifierContexts.AllContext); return new AliasBinding(aliasDef); }else{ this.AddNodePositionAndInfo(identifier, nspace, IdentifierContexts.AllContext); return nspace.Name; } } done: if (inaccessibleType != null) nameBindingMembers = new MemberList(inaccessibleType); else if (nameBindingMembers == null) nameBindingMembers = new MemberList(0); NameBinding result = new NameBinding(identifier, nameBindingMembers, this.scope, lexLevel, identifier.SourceContext); this.AddNodePositionAndInfo(identifier, result, IdentifierContexts.AllContext); return result; }
public virtual Expression VisitNameBinding(NameBinding nameBinding, NameBinding changes, NameBinding deletions, NameBinding insertions){ this.UpdateSourceContext(nameBinding, changes); if (nameBinding == null) return changes; if (changes != null){ if (deletions == null || insertions == null) Debug.Assert(false); else{ } }else if (deletions != null) return null; return nameBinding; }
public override Expression VisitNameBinding(NameBinding nameBinding) { if (nameBinding == null) return null; nameBinding = (NameBinding)nameBinding.Clone(); nameBinding.BoundMember = this.VisitExpression(nameBinding.BoundMember); nameBinding.BoundMembers = this.VisitMemberReferenceList(nameBinding.BoundMembers); return nameBinding; }