private void SetType(JsNode node, IJsTypeInfo type, JsPropertyInfo prop = null, JsMethodSignature sig = null) { var a = node.Annotation<JsNodeTypeAnnotation>() ?? node.AddAnnotation(new JsNodeTypeAnnotation()); if (a.Type != null) a.Type = type; if (a.Property != null) a.Property = prop; if (a.FunctionSignature != null) a.FunctionSignature = sig; }
static IEnumerable <object> getAssignedPath(JsExpression expression, JsNode rootNode) { if (expression is JsIdentifierExpression identifier && !isNameOverriden(identifier.Identifier, identifier, rootNode)) { return new [] { identifier.Identifier } } ;
private void ReplaceNode(JsNode node, JsNode node2) { var parent = GetParent(node); if (parent is JsBlock) { var block = (JsBlock)parent; var index = block.Statements.IndexOf((JsStatement)node); if (index < 0) { throw new Exception("ReplaceNode Failed"); } block.Statements[index] = (JsStatement)node2; return; } foreach (var pe in parent.GetType().GetProperties()) { var obj = pe.GetValue(parent, null); if (obj == node) { pe.SetValue(parent, node2, null); return; } } throw new Exception("ReplaceNode failed"); }
public static JsNode ResolveVariables(JsNode node) { void walkNode(List <(JsNode, bool)> path, JsNode n) { path.Add((n, true)); foreach (var c in n.Children) { walkNode(path, c); } path.Add((n, false)); } var eulerPath = new List <(JsNode node, bool isFirst)>(); walkNode(eulerPath, node); JsNode lca(JsNode a, JsNode b) => a.Ancestors.First(b.Ancestors.Contains); var allVariables = new Dictionary <JsTemporaryVariableParameter, (int, int)>(); var usedNames = new HashSet <string>(); foreach (var n in node.DescendantNodesAndSelf()) { if (n is JsSymbolicParameter symExpr && symExpr.Symbol is JsTemporaryVariableParameter parameter) { if (allVariables.TryGetValue(parameter, out var currentInterval)) { allVariables[parameter] = (Math.Min(currentInterval.Item1, eulerPath.IndexOf((symExpr, true))), Math.Max(currentInterval.Item2, eulerPath.IndexOf((symExpr, false)))); } else { allVariables.Add(parameter, (parameter.Initializer == null ? eulerPath.IndexOf((symExpr, true)) : 0, eulerPath.IndexOf((symExpr, false)))); } } if (n is JsIdentifierExpression identifierExpression) { usedNames.Add(identifierExpression.Identifier); } } if (allVariables.Count == 0) { return(node); } // TODO a?(b = 5 && b + 2):a // a + a + (b) //bool intersects(JsTemporaryVariableParameter a, JsTemporaryVariableParameter b) => var groups = new SortedDictionary <int, List <JsTemporaryVariableParameter> >(); foreach (var k in allVariables.OrderBy(k => k.Value.Item1)) { if (groups.Count > 0 && groups.First() is var first && first.Key < k.Value.Item1) { groups.Remove(first.Key); first.Value.Add(k.Key); groups.Add(k.Value.Item2, first.Value); }
protected override void DefaultVisit(JsNode node) { if (node is JsExpression expression && NeedsParens(expression)) { expression.ReplaceWith(_ => new JsParenthesizedExpression(expression)); } base.DefaultVisit(node); }
void SetParents(JsNode node) { foreach (var ch in node.Children()) { Parents[ch] = node; SetParents(ch); } }
protected override void DefaultVisit(JsNode node) { base.DefaultVisit(node); if (node.Annotation <VMPropertyInfoAnnotation>() is VMPropertyInfoAnnotation propAnnotation) { var target = node.GetChildByRole(JsTreeRoles.TargetExpression); if (target.HasAnnotation <ObservableUnwrapInvocationAnnotation>()) { target = target.GetChildByRole(JsTreeRoles.TargetExpression); } else if (target.HasAnnotation <ObservableSetterInvocationAnnotation>()) { throw new NotImplementedException(); } var propertyType = propAnnotation.MemberInfo.GetResultType(); var containsObservables = true; if (propAnnotation.SerializationMap == null && target?.Annotation <ViewModelInfoAnnotation>() is ViewModelInfoAnnotation targetAnnotation) { propAnnotation.SerializationMap = targetAnnotation.SerializationMap.Properties.FirstOrDefault(p => p.PropertyInfo == propAnnotation.MemberInfo); containsObservables = targetAnnotation.ContainsObservables; } if (propAnnotation.SerializationMap is ViewModelPropertyMap propertyMap) { if (propertyMap.ViewModelProtection == ViewModel.ProtectMode.EncryptData) { throw new Exception($"Property {propAnnotation.MemberInfo.Name} is encrypted and cannot be used in JS."); } if (node is JsMemberAccessExpression memberAccess && propertyMap.Name != memberAccess.MemberName) { memberAccess.MemberName = propertyMap.Name; } } else if (propAnnotation.MemberInfo is FieldInfo) { throw new NotSupportedException($"Can not translate field '{propAnnotation.MemberInfo}' to Javascript"); } if (containsObservables) { node.AddAnnotation(ResultIsObservableAnnotation.Instance); if (ViewModelJsonConverter.IsCollection(propertyType)) { node.AddAnnotation(ResultIsObservableArrayAnnotation.Instance); } } node.AddAnnotation(new ViewModelInfoAnnotation(propertyType, containsObservables: containsObservables)); node.AddAnnotation(MayBeNullAnnotation.Instance); } if (node.Annotation <ViewModelInfoAnnotation>() is var vmAnnotation && vmAnnotation?.Type != null && vmAnnotation.SerializationMap == null) { vmAnnotation.SerializationMap = mapper.GetMap(vmAnnotation.Type); } }
protected override void DefaultVisit(JsNode node) { if (node is JsExpression expression && node.HasAnnotation <ResultIsObservableAnnotation>() && !node.Parent.HasAnnotation <ObservableUnwrapInvocationAnnotation>() && !(node.Role == JsAssignmentExpression.LeftRole && node.Parent is JsAssignmentExpression) && node.Parent != null) { if (!AllowObservableResult || !node.IsRootResultExpression()) { // may be null is copied to the observable result node.ReplaceWith(_ => KoUnwrap(expression, expression, false)); node.RemoveAnnotations <MayBeNullAnnotation>(); } } base.DefaultVisit(node); }
protected override void DefaultVisit(JsNode node) { if (node is JsExpression expression && IsObservableResult(node) && !node.Parent.HasAnnotation <ObservableUnwrapInvocationAnnotation>() && !(node.Role == JsAssignmentExpression.LeftRole && node.Parent is JsAssignmentExpression) && node.Parent != null) { if (ShouldUnwrap(node)) { // may be null is copied to the observable result node.ReplaceWith(_ => KoUnwrap(expression, expression, !node.HasAnnotation <ResultIsObservableAnnotation>())); node.RemoveAnnotations <MayBeNullAnnotation>(); } else { // may be null means that the value in the observable may be null. Which is not unwrapped, so the annotation is removed. node.RemoveAnnotations <MayBeNullAnnotation>(); } }
static bool isNameOverriden(object name, JsNode n, JsNode rootNode) { if (!(name is string)) { return(false); } while (n != null && n != rootNode) { if (n is JsFunctionExpression fExpr && fExpr.Parameters.Any(p => p.Name == (string)name)) { return(true); } n = n.Parent; } return(false); }
private void AssertFormatting(string expectedString, JsNode node) { Assert.AreEqual(expectedString, node.Clone().FormatScript()); foreach (var dd in node.Descendants.OfType <JsExpression>()) { var symbol = new JsSymbolicParameter(new CodeSymbolicParameter()); dd.ReplaceWith(symbol); var parametrized = node.Clone().FormatParametrizedScript(); var resolved = parametrized.ToString(o => o == symbol.Symbol ? CodeParameterAssignment.FromExpression(dd) : throw new Exception()); Assert.AreEqual(expectedString, resolved, $"Replaced expression: {dd.FormatScript()}"); symbol.ReplaceWith(dd); } }
private void ReplaceOrEmit <T>(T node, Func <T, JsNode> replacer) where T : JsNode { if (node.Parent == null) { Debug.Assert(node.Parent == root); node.Remove(); NewExpression = replacer(node); } else { var e = node.ReplaceWith(n => replacer((T)n)); if (node.Parent == root) { NewExpression = e; } } }
void ChangeNullableCtorName(IMember pField, JsNode pNode) { if (!(pField is IField) || !(pNode is JsBinaryExpression)) { return; } var tField = pField as IField; var tNode = pNode as JsBinaryExpression; if (tField.Type == null || tField.Type.Kind != TypeKind.Struct || tField.Type.FullName != "System.Nullable") { return; } var tNode2 = tNode.Right as JsNewObjectExpression; if (tNode2 == null || tNode2.Invocation == null || !(tNode2.Invocation.Member is JsMemberExpression)) { return; } (tNode2.Invocation.Member as JsMemberExpression).Name = "ctor$1"; }
private void HandleNode(JsNode node) { if (node is JsExpression expression2) { foreach (var transform in node.Annotations.OfType <ObservableTransformationAnnotation>()) { node.ReplaceWith(_ => transform.TransformExpression(expression2)); } } if (node is JsExpression expression && IsObservableResult(node) && !node.Parent.HasAnnotation <ObservableUnwrapInvocationAnnotation>() && !(node.Role == JsAssignmentExpression.LeftRole && node.Parent is JsAssignmentExpression) && node.Parent != null) { if (ShouldUnwrap(node)) { // may be null is copied to the observable result node.ReplaceWith(_ => KoUnwrap(expression, expression, !node.HasAnnotation <ResultIsObservableAnnotation>())); node.RemoveAnnotations <MayBeNullAnnotation>(); } else { // may be null means that the value in the observable may be null. Which is not unwrapped, so the annotation is removed. node.RemoveAnnotations <MayBeNullAnnotation>(); } }
public static bool IsRootResultExpression(this JsNode node) => !(node.Parent is JsExpression) || (node.Parent is JsParenthesizedExpression || node.Role == JsConditionalExpression.FalseRole || node.Role == JsConditionalExpression.TrueRole ) && node.Parent.IsRootResultExpression();
JsNode GetParent(JsNode node) { return(Parents.TryGetValue(node)); }
protected virtual void BeforeVisit(JsNode node) { }
public static bool SatisfyResultCondition(this JsNode node, Func <JsNode, bool> predicate) => predicate(node) || (node.Parent is JsParenthesizedExpression || node.Role == JsConditionalExpression.FalseRole || node.Role == JsConditionalExpression.TrueRole ) && node.Parent.SatisfyResultCondition(predicate);
public static bool IsRootResultExpression(this JsNode node) => SatisfyResultCondition(node, n => n.Parent == null || n.Parent is JsExpressionStatement);
protected virtual void AfterVisit(JsNode node) { }
public static bool IsRootResultExpression(this JsNode node) => SatisfyResultCondition(node, n => !(n.Parent is JsExpression));
protected override void DefaultVisit(JsNode node) { base.DefaultVisit(node); HandleNode(node); }
private JsNode WrapSetterToReturnValueIfNeeded(OperatorResolveResult res, JsNode node2) { return(Importer.WrapSetterToReturnValueIfNeeded(res, node2)); }
private bool IsObservableResult(JsNode node) => node.HasAnnotation <ResultIsObservableAnnotation>() || node.HasAnnotation <ResultMayBeObservableAnnotation>();
public void AdjustViewModelProperties(JsNode expr) { expr.AcceptVisitor(new JsViewModelPropertyAdjuster(mapper)); }
public JavascriptNullCheckAdder(JsNode root) { this.root = root; }
public AbstractSyntaxTree(JsNode root) { Status = AbstractSyntaxTreeStatus.Error; Root = root; }
public override void AfterBehaviour() { id = FindChild<IdentifierToken>(false); elements = FindChild("enum-elements"); }
public JsNode UnsafeVisit(IEntity me) { if (CompilerConfiguration.Current.EnableLogging) { Log.Debug("JsTypeImporter: Visit Entity: " + me.ToString()); } if (BeforeVisitEntity != null) { BeforeVisitEntity(me); } JsNode node2 = null; switch (me.SymbolKind) { #region switch case //case EntityType.ent_anonymous_method: // node2 = _Visit((CsEntityAnonymousMethod)me); break; //case EntityType.ent_block: // node2 = _Visit((CsEntityBlock)me); break; //case EntityType.ent_block_variable: // node2 = _Visit((CsEntityBlockVariable)me); break; case SymbolKind.TypeDefinition: node2 = _Visit((ITypeDefinition)me); break; //case EntityType.ent_constant: // node2 = _Visit((IConst)me); break; //case EntityType.ent_delegate: // node2 = _Visit((IDelegate)me); break; //case EntityType.ent_enum: // node2 = _Visit((CsEntityEnum)me); break; case SymbolKind.Event: node2 = _Visit((IEvent)me); break; //case EntityType.ent_formal_parameter: // node2 = _Visit((CsEntityFormalParameter)me); break; //case EntityType.ent_generic_param: // node2 = _Visit((CsEntityGenericParam)me); break; //case EntityType.Interface: // node2 = _Visit((IInterface)me); break; //case EntityType.ent_local_constant: // node2 = _Visit((CsEntityLocalConstant)me); break; //case EntityType.ent_local_variable: // node2 = _Visit((CsEntityLocalVariable)me); break; case SymbolKind.Method: case SymbolKind.Constructor: case SymbolKind.Operator: case SymbolKind.Accessor: node2 = _Visit((IMethod)me); break; //case EntityType.ent_namespace: // node2 = _Visit((CsEntityNamespace)me); break; case SymbolKind.Property: case SymbolKind.Indexer: node2 = _Visit((IProperty)me); break; //case EntityType.ent_struct: // node2 = _Visit((IStruct)me); break; case SymbolKind.Field: node2 = _Visit((IField)me); break; #endregion } if (AfterVisitEntity != null) { AfterVisitEntity(me, node2); } return(node2); }
public virtual void DefaultVisit(JsNode node) { }
private bool NeedsUnwrap(JsNode node) => node.HasAnnotation <ResultIsObservableAnnotation>() || node.HasAnnotation <ResultMayBeObservableAnnotation>();