private IEnumerable <JsStatement> CreateNamespaces(JsExpression root, IEnumerable <string> requiredNamespaces) { return(requiredNamespaces.SelectMany(EntireNamespaceHierarchy) .Distinct() .OrderBy(ns => ns) .Select(ns => { var access = MakeNestedMemberAccess(ns, root); return (JsStatement)JsExpression.Assign(access, JsExpression.LogicalOr(access, JsExpression.ObjectLiteral())); })); }
private JsExpression GetFieldHashCode(IField field) { var impl = _metadataImporter.GetFieldSemantics(field); if (impl.Type != FieldScriptSemantics.ImplType.Field) { return(null); } IType type = NullableType.GetUnderlyingType(field.Type); bool needNullCheck = field.Type.IsReferenceType != false || field.Type.IsKnownType(KnownTypeCode.NullableOfT) || type.Kind == TypeKind.Enum && MetadataUtils.IsNamedValues(field.Type.GetDefinition(), _attributeStore); JsExpression member = JsExpression.Member(JsExpression.This, impl.Name); JsExpression result = JsExpression.Invocation(JsExpression.Member(_systemScript, "getHashCode"), member); if (needNullCheck) { result = JsExpression.Conditional(member, result, JsExpression.Number(0)); } if (type.Kind == TypeKind.Enum && !MetadataUtils.IsNamedValues(type.GetDefinition(), _attributeStore)) { result = needNullCheck ? JsExpression.LogicalOr(member, JsExpression.Number(0)) : member; } else if (type is ITypeDefinition) { switch (((ITypeDefinition)type).KnownTypeCode) { case KnownTypeCode.Boolean: result = JsExpression.Conditional(member, JsExpression.Number(1), JsExpression.Number(0)); break; case KnownTypeCode.Byte: case KnownTypeCode.SByte: case KnownTypeCode.Char: case KnownTypeCode.Int16: case KnownTypeCode.UInt16: case KnownTypeCode.Int32: case KnownTypeCode.UInt32: case KnownTypeCode.Int64: case KnownTypeCode.UInt64: case KnownTypeCode.Decimal: case KnownTypeCode.Single: case KnownTypeCode.Double: result = needNullCheck ? JsExpression.LogicalOr(member, JsExpression.Number(0)) : member; break; } } return(result); }
private bool HandleSwitchStatement(JsSwitchStatement stmt, StackEntry location, ImmutableStack <StackEntry> stack, ImmutableStack <Tuple <string, State> > breakStack, ImmutableStack <Tuple <string, State> > continueStack, State currentState, State returnState, IList <JsStatement> currentBlock) { var stateAfter = GetStateAfterStatement(location, stack, currentState.FinallyStack, returnState); JsExpression expression = stmt.Expression; if (_isExpressionComplexEnoughForATemporaryVariable(expression)) { string newName = _allocateTempVariable(); currentBlock.Add(JsStatement.Var(newName, expression)); expression = JsExpression.Identifier(newName); } var clauses = new List <Tuple <JsExpression, JsBlockStatement> >(); JsStatement defaultClause = null; State? currentFallthroughState = null; for (int i = 0; i < stmt.Sections.Count; i++) { var clause = stmt.Sections[i]; var origBody = new List <JsStatement>(); origBody.AddRange(clause.Body.Statements); State?nextFallthroughState; if (i < stmt.Sections.Count - 1 && (origBody.Count == 0 || IsNextStatementReachable(origBody[origBody.Count - 1]))) { // Fallthrough var nextBody = stmt.Sections[i + 1].Body.Statements; if (nextBody.Count > 0 && nextBody[0] is JsLabelledStatement) { nextFallthroughState = GetOrCreateStateForLabel(((JsLabelledStatement)nextBody[0]).Label, currentState.FinallyStack); } else { nextFallthroughState = CreateNewStateValue(currentState.FinallyStack); } } else { nextFallthroughState = null; } breakStack = breakStack.Push(Tuple.Create(GetLabelForState(currentState), stateAfter.Item1)); IList <JsStatement> body; if (currentFallthroughState != null) { body = new List <JsStatement>(); body.Add(new JsGotoStateStatement(currentFallthroughState.Value, currentState)); Enqueue(ImmutableStack <StackEntry> .Empty.Push(new StackEntry(JsStatement.Block(origBody), 0)), breakStack, continueStack, currentFallthroughState.Value, stateAfter.Item1); } else { body = Handle(ImmutableStack <StackEntry> .Empty.Push(new StackEntry(JsStatement.Block(origBody), 0)), breakStack, continueStack, currentState, nextFallthroughState ?? stateAfter.Item1, false, false); } if (clause.Values.Any(v => v == null)) { defaultClause = JsStatement.Block(body); } else { JsExpression test = clause.Values.Select(v => JsExpression.Same(expression, v)).Aggregate((o, e) => o != null ? JsExpression.LogicalOr(o, e) : e); clauses.Add(Tuple.Create(test, JsStatement.Block(body))); } currentFallthroughState = nextFallthroughState; } clauses.Reverse(); currentBlock.Add(clauses.Where(c => c.Item1 != null).Aggregate(defaultClause, (o, n) => JsStatement.If(n.Item1, n.Item2, o))); currentBlock.Add(new JsGotoStateStatement(stateAfter.Item1, currentState)); if (stateAfter.Item2) { Enqueue(PushFollowing(stack, location), breakStack, continueStack, stateAfter.Item1, returnState); return(false); } return(true); }