private string TransformMember(MemberSymbol memberSymbol) { TypeSymbol type = (TypeSymbol)memberSymbol.Parent; if (((memberSymbol.Visibility & MemberVisibility.Public) != 0) || ((memberSymbol.Visibility & MemberVisibility.Protected) != 0) || (memberSymbol.IsTransformAllowed == false)) { return null; } if ((memberSymbol.Visibility & MemberVisibility.Internal) != 0) { return GenerateName(memberSymbol.Name); } else { // We add the inheritance depth, because two classes in the // same type hierarchy can have similar named private methods // which end up overriding each other in the generated script. // In release mode, these will get transformed into generated // names, so this type of disambiguation needs to be done for // debug builds only. int inheritanceDepth = 0; if (type.Type == SymbolType.Class) { inheritanceDepth = ((ClassSymbol)type).InheritanceDepth; } if (inheritanceDepth != 0) { string generatedName = GenerateName(memberSymbol.Name); if (generatedName == null) { // Can be null if the member was already prefixed with // a "_" generatedName = memberSymbol.Name; } return generatedName + "$" + inheritanceDepth; } return GenerateName(memberSymbol.Name); } }
private static void GenerateBlockStatement(ScriptGenerator generator, MemberSymbol symbol, BlockStatement statement) { ScriptTextWriter writer = generator.Writer; foreach (Statement s in statement.Statements) { GenerateStatement(generator, symbol, s); } }
private static void GenerateForStatement(ScriptGenerator generator, MemberSymbol symbol, ForStatement statement) { if (statement.Body == null) { return; } ScriptTextWriter writer = generator.Writer; writer.WriteTrimmed("for "); writer.Write("("); if (statement.Initializers != null) { ExpressionGenerator.GenerateExpressionList(generator, symbol, statement.Initializers); } else if (statement.Variables != null) { GenerateVariableDeclarations(generator, symbol, statement.Variables); } writer.WriteTrimmed("; "); if (statement.Condition != null) { ExpressionGenerator.GenerateExpression(generator, symbol, statement.Condition); } writer.WriteTrimmed("; "); if (statement.Increments != null) { ExpressionGenerator.GenerateExpressionList(generator, symbol, statement.Increments); } writer.WriteTrimmed(") "); writer.Write("{"); writer.WriteNewLine(); writer.Indent++; GenerateStatement(generator, symbol, statement.Body); writer.Indent--; writer.Write("}"); writer.WriteNewLine(); }
public static void GenerateScript(ScriptGenerator generator, MemberSymbol memberSymbol) { Debug.Assert(memberSymbol.Parent is TypeSymbol); TypeSymbol typeSymbol = (TypeSymbol)memberSymbol.Parent; string typeName = typeSymbol.FullGeneratedName; switch (memberSymbol.Type) { case SymbolType.Field: GenerateField(generator, typeName, (FieldSymbol)memberSymbol); break; case SymbolType.Indexer: GenerateIndexer(generator, typeName, (IndexerSymbol)memberSymbol); break; case SymbolType.Property: GenerateProperty(generator, typeName, (PropertySymbol)memberSymbol); break; case SymbolType.Method: GenerateMethod(generator, typeName, (MethodSymbol)memberSymbol); break; case SymbolType.Event: GenerateEvent(generator, typeName, (EventSymbol)memberSymbol); break; } }
public MemberExpression(Expression objectReference, MemberSymbol member) : base(ExpressionType.Member, (member.AssociatedType.Type == SymbolType.GenericParameter ? objectReference.EvaluatedType : member.AssociatedType), SymbolFilter.Public | SymbolFilter.InstanceMembers) { _member = member; _objectReference = objectReference; }
private static void GenerateErrorStatement(ScriptGenerator generator, MemberSymbol symbol, ErrorStatement statement) { ScriptTextWriter writer = generator.Writer; writer.Write("// ERROR: "); writer.Write(statement.Message); writer.WriteSignificantNewLine(); writer.Write("// ERROR: at "); writer.Write(statement.Location); writer.WriteSignificantNewLine(); }
private static void GenerateExpressionStatement(ScriptGenerator generator, MemberSymbol symbol, ExpressionStatement statement) { ScriptTextWriter writer = generator.Writer; ExpressionGenerator.GenerateExpression(generator, symbol, statement.Expression); if (statement.IsFragment == false) { writer.Write(";"); writer.WriteNewLine(); } }
public override void AddMember(MemberSymbol memberSymbol) { Debug.Assert(memberSymbol != null); if (memberSymbol.Type == SymbolType.Indexer) { Debug.Assert(_indexer == null); _indexer = (IndexerSymbol)memberSymbol; } else { base.AddMember(memberSymbol); } }
public static void GenerateStatement(ScriptGenerator generator, MemberSymbol symbol, Statement statement) { switch (statement.Type) { case StatementType.Block: GenerateBlockStatement(generator, symbol, (BlockStatement)statement); break; case StatementType.Empty: break; case StatementType.VariableDeclaration: GenerateVariableDeclarationStatement(generator, symbol, (VariableDeclarationStatement)statement); break; case StatementType.Return: GenerateReturnStatement(generator, symbol, (ReturnStatement)statement); break; case StatementType.Expression: GenerateExpressionStatement(generator, symbol, (ExpressionStatement)statement); break; case StatementType.IfElse: GenerateIfElseStatement(generator, symbol, (IfElseStatement)statement); break; case StatementType.While: GenerateWhileStatement(generator, symbol, (WhileStatement)statement); break; case StatementType.For: GenerateForStatement(generator, symbol, (ForStatement)statement); break; case StatementType.ForIn: GenerateForInStatement(generator, symbol, (ForInStatement)statement); break; case StatementType.Switch: GenerateSwitchStatement(generator, symbol, (SwitchStatement)statement); break; case StatementType.Break: GenerateBreakStatement(generator, symbol, (BreakStatement)statement); break; case StatementType.Continue: GenerateContinueStatement(generator, symbol, (ContinueStatement)statement); break; case StatementType.Throw: GenerateThrowStatement(generator, symbol, (ThrowStatement)statement); break; case StatementType.TryCatchFinally: GenerateTryCatchFinallyStatement(generator, symbol, (TryCatchFinallyStatement)statement); break; case StatementType.Error: GenerateErrorStatement(generator, symbol, (ErrorStatement)statement); break; default: Debug.Fail("Unexpected statement type: " + statement.Type); break; } }
private static void GenerateBaseInitializerExpression(ScriptGenerator generator, MemberSymbol symbol, BaseInitializerExpression expression) { ScriptTextWriter writer = generator.Writer; Debug.Assert(symbol.Parent is ClassSymbol); writer.Write(((ClassSymbol)symbol.Parent).FullGeneratedName); writer.Write(".initializeBase(this"); if (expression.Parameters != null) { writer.Write(","); writer.WriteTrimmed(" [ "); GenerateExpressionList(generator, symbol, expression.Parameters); writer.WriteTrimmed(" ]"); } writer.Write(")"); }
private void BuildMemberDetails(MemberSymbol memberSymbol, TypeSymbol typeSymbol, MemberNode memberNode, ParseNodeList attributes) { if (memberSymbol.Type != SymbolType.EnumerationField) { memberSymbol.SetVisibility(GetVisibility(memberNode, typeSymbol)); } bool preserveCase = (AttributeNode.FindAttribute(attributes, "PreserveCase") != null); memberSymbol.SetNameCasing(preserveCase); string scriptName = GetAttributeValue(attributes, "ScriptName"); if (scriptName != null) { memberSymbol.SetTransformedName(scriptName); } else if (AttributeNode.FindAttribute(attributes, "PreserveName") != null) { memberSymbol.DisableNameTransformation(); } }
private static void GenerateTypeExpression(ScriptGenerator generator, MemberSymbol symbol, TypeExpression expression) { ScriptTextWriter writer = generator.Writer; writer.Write(expression.AssociatedType.FullGeneratedName); }
private static void GenerateLiteralExpression(ScriptGenerator generator, MemberSymbol symbol, LiteralExpression expression) { ScriptTextWriter writer = generator.Writer; object value = expression.Value; string textValue = null; if (value == null) { textValue = "null"; } else { if (value is bool) { if ((bool)value) { textValue = "true"; } else { textValue = "false"; } } else if ((value is char) || (value is string)) { textValue = Utility.QuoteString(value.ToString()); } else if (value is TypeSymbol) { textValue = ((TypeSymbol)value).FullGeneratedName; } else if (value is Expression[]) { Expression[] values = (Expression[])value; if (values.Length == 0) { textValue = "[]"; } else { writer.WriteTrimmed("[ "); GenerateExpressionList(generator, symbol, (Expression[])value); writer.WriteTrimmed(" ]"); } } else { textValue = Convert.ToString(value, CultureInfo.InvariantCulture); } } if (textValue != null) { writer.Write(textValue); } }
private static void GenerateInlineScriptExpression(ScriptGenerator generator, MemberSymbol symbol, InlineScriptExpression expression) { ScriptTextWriter writer = generator.Writer; string script = expression.Script; ICollection<Expression> parameters = expression.Parameters; if (parameters != null) { Debug.Assert(parameters.Count != 0); string[] parameterScripts = new string[parameters.Count]; int i = 0; foreach (Expression parameterExpression in parameters) { StringWriter sw = new StringWriter(); try { writer.StartLocalWriting(sw); ExpressionGenerator.GenerateExpression(generator, symbol, parameterExpression); parameterScripts[i] = sw.ToString(); i++; } finally { writer.StopLocalWriting(); } } script = String.Format(script, parameterScripts); } writer.Write(script); }
private static void GenerateFieldExpression(ScriptGenerator generator, MemberSymbol symbol, FieldExpression expression) { ScriptTextWriter writer = generator.Writer; if (expression.Field.IsGlobalField) { writer.Write(expression.Field.GeneratedName); } else { ExpressionGenerator.GenerateExpression(generator, symbol, expression.ObjectReference); writer.Write("."); writer.Write(expression.Field.GeneratedName); } }
private static void GenerateEventExpression(ScriptGenerator generator, MemberSymbol symbol, EventExpression expression) { ScriptTextWriter writer = generator.Writer; ExpressionGenerator.GenerateExpression(generator, symbol, expression.ObjectReference); if (expression.Type == ExpressionType.EventAdd) { writer.Write(".add_"); } else { writer.Write(".remove_"); } writer.Write(expression.Event.GeneratedName); writer.Write("("); ExpressionGenerator.GenerateExpression(generator, symbol, expression.Handler); writer.Write(")"); }
private string TransformMember(MemberSymbol memberSymbol) { if ((memberSymbol.InterfaceMember != null) || (memberSymbol.Name.Length < 3) || (memberSymbol.IsTransformAllowed == false)) { // Interface members do get obfuscated // Also members with already short names do not get // obfuscated, as doing so might infact increase the name size return(null); } TypeSymbol type = (TypeSymbol)memberSymbol.Parent; if (memberSymbol.IsPublic == false) { if ((memberSymbol is CodeMemberSymbol) && ((CodeMemberSymbol)memberSymbol).IsOverride) { ClassSymbol baseType = ((ClassSymbol)type).BaseClass; if (baseType == null) { baseType = (ClassSymbol)((ISymbolTable)memberSymbol.SymbolSet.SystemNamespace).FindSymbol("Object", null, SymbolFilter.Types); Debug.Assert(baseType != null); } MemberSymbol baseMember = (MemberSymbol)((ISymbolTable)baseType).FindSymbol(memberSymbol.Name, type, SymbolFilter.Members); Debug.Assert(baseMember != null); return(baseMember.GeneratedName); } else { int minimizationDepth = 0; int currentCount = -1; if (type is ClassSymbol) { currentCount = ((ClassSymbol)type).TransformationCookie; } else if (type is EnumerationSymbol) { currentCount = ((EnumerationSymbol)type).TransformationCookie; } if (type is ClassSymbol) { minimizationDepth = ((ClassSymbol)type).MinimizationDepth; if (currentCount == -1) { ClassSymbol baseClass = ((ClassSymbol)type).BaseClass; if ((baseClass != null) && baseClass.IsApplicationType) { // Set current count to the base classes transformation // cookie, so the generated one will the next one in // sequence currentCount = baseClass.TransformationCookie; } } } currentCount++; if (type is ClassSymbol) { ((ClassSymbol)type).TransformationCookie = currentCount; } else if (type is EnumerationSymbol) { ((EnumerationSymbol)type).TransformationCookie = currentCount; } return(GenerateName(currentCount, minimizationDepth)); } } return(null); }
protected LocalSymbol(SymbolType type, string name, MemberSymbol parent, TypeSymbol valueType) : base(type, name, parent) { _valueType = valueType; }
private static void GenerateEnumerationFieldExpression(ScriptGenerator generator, MemberSymbol symbol, EnumerationFieldExpression expression) { ScriptTextWriter writer = generator.Writer; ExpressionGenerator.GenerateExpression(generator, symbol, expression.ObjectReference); writer.Write("."); writer.Write(expression.Field.GeneratedName); }
public VariableSymbol(string name, MemberSymbol parent, TypeSymbol valueType) : base(SymbolType.Variable, name, parent, valueType) { }
private static void GenerateExpressionListAsNameValuePairs(ScriptGenerator generator, MemberSymbol symbol, ICollection<Expression> expressions) { Debug.Assert(expressions.Count % 2 == 0); ScriptTextWriter writer = generator.Writer; bool firstExpression = true; bool valueExpression = false; foreach (Expression expression in expressions) { if ((firstExpression == false) && (valueExpression == false)) { writer.WriteTrimmed(", "); } if (valueExpression) { writer.WriteTrimmed(": "); GenerateExpression(generator, symbol, expression); valueExpression = false; } else { Debug.Assert(expression.Type == ExpressionType.Literal); Debug.Assert(((LiteralExpression)expression).Value is string); string name = (string)((LiteralExpression)expression).Value; if (Utility.IsValidIdentifier(name)) { writer.Write(name); } else { writer.Write(Utility.QuoteString(name)); } valueExpression = true; } firstExpression = false; } }
private MemberSymbol CreateGenericMember(MemberSymbol templateMember, IList <TypeSymbol> typeArguments) { TypeSymbol parentType = (TypeSymbol)templateMember.Parent; TypeSymbol instanceAssociatedType; if (templateMember.AssociatedType.Type == SymbolType.GenericParameter) { GenericParameterSymbol genericParameter = (GenericParameterSymbol)templateMember.AssociatedType; instanceAssociatedType = typeArguments[genericParameter.Index]; } else { instanceAssociatedType = typeArguments[0]; } if (templateMember.Type == SymbolType.Indexer) { IndexerSymbol templateIndexer = (IndexerSymbol)templateMember; IndexerSymbol instanceIndexer = new IndexerSymbol(parentType, instanceAssociatedType); if (templateIndexer.UseScriptIndexer) { instanceIndexer.SetScriptIndexer(); } instanceIndexer.SetVisibility(templateIndexer.Visibility); return(instanceIndexer); } else if (templateMember.Type == SymbolType.Property) { PropertySymbol templateProperty = (PropertySymbol)templateMember; PropertySymbol instanceProperty = new PropertySymbol(templateProperty.Name, parentType, instanceAssociatedType); if (templateProperty.IsTransformed) { instanceProperty.SetTransformedName(templateProperty.GeneratedName); } instanceProperty.SetNameCasing(templateProperty.IsCasePreserved); instanceProperty.SetVisibility(templateProperty.Visibility); return(instanceProperty); } else if (templateMember.Type == SymbolType.Field) { FieldSymbol templateField = (FieldSymbol)templateMember; FieldSymbol instanceField = new FieldSymbol(templateField.Name, parentType, instanceAssociatedType); if (templateField.IsTransformed) { instanceField.SetTransformedName(templateField.GeneratedName); } instanceField.SetNameCasing(templateField.IsCasePreserved); instanceField.SetVisibility(templateField.Visibility); return(instanceField); } else if (templateMember.Type == SymbolType.Method) { MethodSymbol templateMethod = (MethodSymbol)templateMember; MethodSymbol instanceMethod = new MethodSymbol(templateMethod.Name, parentType, instanceAssociatedType); if (templateMethod.IsAliased) { instanceMethod.SetAlias(templateMethod.Alias); } else if (templateMethod.IsTransformed) { instanceMethod.SetTransformedName(templateMethod.GeneratedName); } if (templateMethod.SkipGeneration) { instanceMethod.SetSkipGeneration(); } if (templateMethod.InterfaceMember != null) { instanceMethod.SetInterfaceMember(templateMethod.InterfaceMember); } instanceMethod.SetNameCasing(templateMethod.IsCasePreserved); instanceMethod.SetVisibility(templateMethod.Visibility); return(instanceMethod); } Debug.Fail("Unexpected generic member '" + templateMember.Name + " on type '" + ((TypeSymbol)templateMember.Parent).FullName + "'."); return(null); }
private static void GenerateIndexerExpression(ScriptGenerator generator, MemberSymbol symbol, IndexerExpression expression) { ScriptTextWriter writer = generator.Writer; if (expression.Indexer.IsIntrinsic) { GenerateExpression(generator, symbol, expression.ObjectReference); writer.Write("["); GenerateExpressionList(generator, symbol, expression.Indices); writer.Write("]"); } else if (expression.ObjectReference is BaseExpression) { Debug.Assert(symbol.Parent is ClassSymbol); writer.Write(((ClassSymbol)symbol.Parent).FullGeneratedName); writer.Write(".callBaseMethod(this, 'get_"); writer.Write(expression.Indexer.GeneratedName); writer.Write("',"); writer.WriteTrimmed(" [ "); GenerateExpressionList(generator, symbol, expression.Indices); writer.WriteTrimmed(" ])"); } else { GenerateExpression(generator, expression.Indexer, expression.ObjectReference); writer.Write(".get_"); writer.Write(expression.Indexer.GeneratedName); writer.Write("("); GenerateExpressionList(generator, expression.Indexer, expression.Indices); writer.Write(")"); } }
private void CreateGenericTypeMembers(TypeSymbol templateType, TypeSymbol instanceType, IList <TypeSymbol> typeArguments) { foreach (MemberSymbol memberSymbol in templateType.Members) { if ((memberSymbol.AssociatedType.Type == SymbolType.GenericParameter) && ((GenericParameterSymbol)memberSymbol.AssociatedType).IsTypeParameter) { MemberSymbol instanceMemberSymbol = CreateGenericMember(memberSymbol, typeArguments); instanceType.AddMember(instanceMemberSymbol); } else if (memberSymbol.AssociatedType.IsGeneric && (memberSymbol.AssociatedType.GenericArguments == null) && (memberSymbol.AssociatedType.GenericParameters.Count == typeArguments.Count)) { TypeSymbol genericType = CreateGenericTypeSymbol(memberSymbol.AssociatedType, typeArguments); if (genericType == null) { genericType = instanceType; } List <TypeSymbol> memberTypeArgs = new List <TypeSymbol>() { genericType }; MemberSymbol instanceMemberSymbol = CreateGenericMember(memberSymbol, memberTypeArgs); instanceType.AddMember(instanceMemberSymbol); } else { instanceType.AddMember(memberSymbol); } } IndexerSymbol indexer = null; if (templateType.Type == SymbolType.Class) { indexer = ((ClassSymbol)templateType).Indexer; } else if (templateType.Type == SymbolType.Interface) { indexer = ((InterfaceSymbol)templateType).Indexer; } if (indexer != null) { if (indexer.AssociatedType.Type == SymbolType.GenericParameter) { MemberSymbol instanceIndexer = CreateGenericMember(indexer, typeArguments); instanceType.AddMember(instanceIndexer); } else if (indexer.AssociatedType.IsGeneric && (indexer.AssociatedType.GenericArguments == null) && (indexer.AssociatedType.GenericParameters.Count == typeArguments.Count)) { TypeSymbol genericType = CreateGenericTypeSymbol(indexer.AssociatedType, typeArguments); if (genericType == null) { genericType = instanceType; } List <TypeSymbol> memberTypeArgs = new List <TypeSymbol>() { genericType }; MemberSymbol instanceMemberSymbol = CreateGenericMember(indexer, memberTypeArgs); instanceType.AddMember(instanceMemberSymbol); } else { instanceType.AddMember(indexer); } } }
private static void GenerateLateBoundExpression(ScriptGenerator generator, MemberSymbol symbol, LateBoundExpression expression) { ScriptTextWriter writer = generator.Writer; string name = null; LiteralExpression literalNameExpression = expression.NameExpression as LiteralExpression; if (literalNameExpression != null) { Debug.Assert(literalNameExpression.Value is string); name = (string)literalNameExpression.Value; Debug.Assert(String.IsNullOrEmpty(name) == false); } if (expression.Operation == LateBoundOperation.DeleteField) { writer.Write("delete "); } if (expression.Operation == LateBoundOperation.GetScriptType) { writer.Write("typeof("); } else if ((expression.Operation == LateBoundOperation.HasMethod) || (expression.Operation == LateBoundOperation.HasProperty)) { writer.Write("(typeof("); } else if (expression.Operation == LateBoundOperation.HasField) { writer.Write("("); GenerateExpression(generator, symbol, expression.NameExpression); writer.Write(" in "); } if (expression.ObjectReference != null) { GenerateExpression(generator, symbol, expression.ObjectReference); } switch (expression.Operation) { case LateBoundOperation.InvokeMethod: if (Utility.IsValidIdentifier(name)) { if (expression.ObjectReference != null) { writer.Write("."); } writer.Write(name); } else { writer.Write("["); GenerateExpression(generator, symbol, expression.NameExpression); writer.Write("]"); } writer.Write("("); if (expression.Parameters.Count != 0) { GenerateExpressionList(generator, symbol, expression.Parameters); } writer.Write(")"); break; case LateBoundOperation.GetField: if (Utility.IsValidIdentifier(name)) { writer.Write("."); writer.Write(name); } else { writer.Write("["); GenerateExpression(generator, symbol, expression.NameExpression); writer.Write("]"); } break; case LateBoundOperation.SetField: if (Utility.IsValidIdentifier(name)) { writer.Write("."); writer.Write(name); } else { writer.Write("["); GenerateExpression(generator, symbol, expression.NameExpression); writer.Write("]"); } writer.WriteTrimmed(" = "); GenerateExpressionList(generator, symbol, expression.Parameters); break; case LateBoundOperation.DeleteField: if (Utility.IsValidIdentifier(name)) { writer.Write("."); writer.Write(name); } else { writer.Write("["); GenerateExpression(generator, symbol, expression.NameExpression); writer.Write("]"); } break; case LateBoundOperation.GetProperty: if (Utility.IsValidIdentifier(name)) { writer.Write(".get_"); writer.Write(name); } else { writer.Write("['get_'"); writer.WriteTrimmed(" + "); GenerateExpression(generator, symbol, expression.NameExpression); writer.Write("]"); } writer.Write("()"); break; case LateBoundOperation.SetProperty: if (Utility.IsValidIdentifier(name)) { writer.Write(".set_"); writer.Write(name); } else { writer.Write("['set_'"); writer.WriteTrimmed(" + "); GenerateExpression(generator, symbol, expression.NameExpression); writer.Write("]"); } writer.Write("("); GenerateExpressionList(generator, symbol, expression.Parameters); writer.Write(")"); break; case LateBoundOperation.AddHandler: if (Utility.IsValidIdentifier(name)) { writer.Write(".add_"); writer.Write(name); } else { writer.Write("['add_'"); writer.WriteTrimmed(" + "); GenerateExpression(generator, symbol, expression.NameExpression); writer.Write("]"); } writer.Write("("); GenerateExpressionList(generator, symbol, expression.Parameters); writer.Write(")"); break; case LateBoundOperation.RemoveHandler: if (Utility.IsValidIdentifier(name)) { writer.Write(".remove_"); writer.Write(name); } else { writer.Write("['remove_'"); writer.WriteTrimmed(" + "); GenerateExpression(generator, symbol, expression.NameExpression); writer.Write("]"); } writer.Write("("); GenerateExpressionList(generator, symbol, expression.Parameters); writer.Write(")"); break; case LateBoundOperation.GetScriptType: writer.Write(")"); break; case LateBoundOperation.HasField: writer.Write(")"); break; case LateBoundOperation.HasMethod: if (Utility.IsValidIdentifier(name)) { if (expression.ObjectReference != null) { writer.Write("."); } writer.Write(name); } else { writer.Write("["); GenerateExpression(generator, symbol, expression.NameExpression); writer.Write("]"); } writer.Write(")"); writer.WriteTrimmed(" === "); writer.Write("'function'"); writer.Write(")"); break; case LateBoundOperation.HasProperty: if (Utility.IsValidIdentifier(name)) { writer.Write(".get_"); writer.Write(name); } else { writer.Write("['get_'"); writer.WriteTrimmed(" + "); GenerateExpression(generator, symbol, expression.NameExpression); writer.Write("]"); } writer.Write(")"); writer.WriteTrimmed(" === "); writer.Write("'function'"); writer.Write(")"); break; } }
private static void GenerateMethodExpression(ScriptGenerator generator, MemberSymbol symbol, MethodExpression expression) { ScriptTextWriter writer = generator.Writer; if (expression.Method.SkipGeneration) { // If this method is to be skipped from generation, just generate the // left-hand-side object reference, and skip everything past it, including // the dot. GenerateExpression(generator, symbol, expression.ObjectReference); return; } if (expression.ObjectReference is BaseExpression) { Debug.Assert(symbol.Parent is ClassSymbol); Debug.Assert(expression.Method.IsGlobalMethod == false); writer.Write(((ClassSymbol)symbol.Parent).FullGeneratedName); writer.Write(".callBaseMethod(this, '"); writer.Write(expression.Method.GeneratedName); writer.Write("'"); if ((expression.Parameters != null) && (expression.Parameters.Count != 0)) { writer.Write(","); writer.WriteTrimmed(" [ "); GenerateExpressionList(generator, symbol, expression.Parameters); writer.WriteTrimmed(" ]"); } writer.Write(")"); } else { if (expression.Method.IsGlobalMethod) { if (expression.Method.Parent is ClassSymbol) { string mixinRoot = ((ClassSymbol)expression.Method.Parent).MixinRoot; if (String.IsNullOrEmpty(mixinRoot) == false) { writer.Write(mixinRoot); writer.Write("."); } } } else { GenerateExpression(generator, symbol, expression.ObjectReference); if (expression.Method.GeneratedName.Length != 0) { writer.Write("."); } } if (expression.Method.GeneratedName.Length != 0) { writer.Write(expression.Method.GeneratedName); } writer.Write("("); if (expression.Parameters != null) { GenerateExpressionList(generator, symbol, expression.Parameters); } writer.Write(")"); } }
private static void GenerateLocalExpression(ScriptGenerator generator, MemberSymbol symbol, LocalExpression expression) { ScriptTextWriter writer = generator.Writer; writer.Write(expression.Symbol.GeneratedName); }
private static void GeneratePropertyExpression(ScriptGenerator generator, MemberSymbol symbol, PropertyExpression expression) { Debug.Assert(expression.Type == ExpressionType.PropertyGet); ScriptTextWriter writer = generator.Writer; if (expression.ObjectReference is BaseExpression) { Debug.Assert(symbol.Parent is ClassSymbol); writer.Write(((ClassSymbol)symbol.Parent).FullGeneratedName); writer.Write(".callBaseMethod(this, 'get_"); writer.Write(expression.Property.GeneratedName); writer.Write("')"); } else { ExpressionGenerator.GenerateExpression(generator, symbol, expression.ObjectReference); writer.Write(".get_"); writer.Write(expression.Property.GeneratedName); writer.Write("()"); } }
private static void GenerateNewExpression(ScriptGenerator generator, MemberSymbol symbol, NewExpression expression) { ScriptTextWriter writer = generator.Writer; if (expression.IsSpecificType) { string type = expression.AssociatedType.FullGeneratedName; if (type.Equals("Array")) { if (expression.Parameters == null) { writer.Write("[]"); } else if ((expression.Parameters.Count == 1) && (expression.Parameters[0].EvaluatedType == symbol.SymbolSet.ResolveIntrinsicType(IntrinsicType.Integer))) { writer.Write("new Array("); GenerateExpression(generator, symbol, expression.Parameters[0]); writer.Write(")"); } else { writer.Write("["); GenerateExpressionList(generator, symbol, expression.Parameters); writer.Write("]"); } return; } else if (type.Equals("Object")) { if (expression.Parameters == null) { writer.Write("{}"); } else { writer.WriteTrimmed("{ "); GenerateExpressionListAsNameValuePairs(generator, symbol, expression.Parameters); writer.WriteTrimmed(" }"); } return; } else if (expression.AssociatedType.Type == SymbolType.Record) { if (expression.AssociatedType.IgnoreNamespace == false) { writer.Write(expression.AssociatedType.GeneratedNamespace); writer.Write("."); } writer.Write("$create_"); writer.Write(expression.AssociatedType.GeneratedName); writer.Write("("); if (expression.Parameters != null) { GenerateExpressionList(generator, symbol, expression.Parameters); } writer.Write(")"); return; } } writer.Write("new "); if (expression.IsSpecificType) { writer.Write(expression.AssociatedType.FullGeneratedName); } else { GenerateExpression(generator, symbol, expression.TypeExpression); } writer.Write("("); if (expression.Parameters != null) { GenerateExpressionList(generator, symbol, expression.Parameters); } writer.Write(")"); }
private static void GenerateBinaryExpression(ScriptGenerator generator, MemberSymbol symbol, BinaryExpression expression) { ScriptTextWriter writer = generator.Writer; if (expression.Operator == Operator.Equals) { PropertyExpression propExpression = expression.LeftOperand as PropertyExpression; if (propExpression != null) { Debug.Assert(propExpression.Type == ExpressionType.PropertySet); if (propExpression.ObjectReference is BaseExpression) { Debug.Assert(symbol.Parent is ClassSymbol); writer.Write(((ClassSymbol)symbol.Parent).FullGeneratedName); writer.Write(".callBaseMethod(this, 'set_"); writer.Write(propExpression.Property.GeneratedName); writer.Write("',"); writer.WriteTrimmed(" [ "); GenerateExpression(generator, symbol, expression.RightOperand); writer.WriteTrimmed(" ])"); } else { GenerateExpression(generator, symbol, propExpression.ObjectReference); writer.Write(".set_"); writer.Write(propExpression.Property.GeneratedName); writer.Write("("); GenerateExpression(generator, symbol, expression.RightOperand); writer.Write(")"); } return; } IndexerExpression indexExpression = expression.LeftOperand as IndexerExpression; if ((indexExpression != null) && !indexExpression.Indexer.IsIntrinsic) { Debug.Assert(indexExpression.Type == ExpressionType.Indexer); if (indexExpression.ObjectReference is BaseExpression) { Debug.Assert(symbol.Parent is ClassSymbol); writer.Write(((ClassSymbol)symbol.Parent).FullGeneratedName); writer.Write(".callBaseMethod(this, 'set_"); writer.Write(indexExpression.Indexer.GeneratedName); writer.Write("',"); writer.WriteTrimmed(" [ "); GenerateExpressionList(generator, symbol, indexExpression.Indices); writer.WriteTrimmed(", "); GenerateExpression(generator, symbol, expression.RightOperand); writer.WriteTrimmed(" ])"); } else { IndexerSymbol indexerSymbol = indexExpression.Indexer; GenerateExpression(generator, symbol, indexExpression.ObjectReference); writer.Write(".set_"); writer.Write(indexerSymbol.GeneratedName); writer.Write("("); GenerateExpressionList(generator, symbol, indexExpression.Indices); writer.WriteTrimmed(", "); GenerateExpression(generator, symbol, expression.RightOperand); writer.Write(")"); } return; } } else if ((expression.Operator == Operator.PlusEquals) || (expression.Operator == Operator.MinusEquals) || (expression.Operator == Operator.MultiplyEquals) || (expression.Operator == Operator.DivideEquals) || (expression.Operator == Operator.ModEquals) || (expression.Operator == Operator.BitwiseOrEquals) || (expression.Operator == Operator.BitwiseAndEquals) || (expression.Operator == Operator.BitwiseXorEquals) || (expression.Operator == Operator.ShiftLeftEquals) || (expression.Operator == Operator.ShiftRightEquals) || (expression.Operator == Operator.UnsignedShiftRightEquals)) { PropertyExpression propExpression = expression.LeftOperand as PropertyExpression; if (propExpression != null) { Debug.Assert(propExpression.Type == ExpressionType.PropertyGet); GenerateExpression(generator, symbol, propExpression.ObjectReference); writer.Write(".set_"); writer.Write(propExpression.Property.GeneratedName); writer.Write("("); GenerateExpression(generator, symbol, propExpression.ObjectReference); writer.Write(".get_"); writer.Write(propExpression.Property.GeneratedName); writer.WriteTrimmed("()"); writer.WriteTrimmed(OperatorConverter.OperatorToString(expression.Operator - 1)); GenerateExpression(generator, symbol, expression.RightOperand); writer.Write(")"); return; } } else if ((expression.Operator == Operator.Is) || (expression.Operator == Operator.As)) { TypeExpression typeExpression = expression.RightOperand as TypeExpression; Debug.Assert(typeExpression != null); writer.Write("Type."); if (expression.Operator == Operator.Is) { writer.Write("canCast("); } else { writer.Write("safeCast("); } GenerateExpression(generator, symbol, expression.LeftOperand); writer.WriteTrimmed(", "); writer.Write(typeExpression.AssociatedType.FullGeneratedName); writer.Write(")"); return; } else if ((expression.Operator == Operator.EqualEqualEqual) || (expression.Operator == Operator.NotEqualEqual)) { LiteralExpression literalExpression = expression.RightOperand as LiteralExpression; if (literalExpression != null) { // Optimize generated script to perform loose equality checks for false-y values // (null, false, 0, empty string) // TODO: This should really be happening at compilation time, rather than generation // time. Because this is happening at generation time, we get something like // if (!!x) when if(x) would suffice just so we can get // foo(!!x) where foo is a method expecting a boolean. // Doing this at compilation time would allow handling if scenarios specially. bool optimizable = false; bool checkForFalse = false; if (literalExpression.Value is bool) { optimizable = true; bool compareValue = (bool)literalExpression.Value; if ((compareValue && (expression.Operator == Operator.NotEqualEqual)) || (!compareValue && (expression.Operator == Operator.EqualEqualEqual))) { checkForFalse = true; } } else if ((literalExpression.Value is int) && (((int)literalExpression.Value) == 0)) { optimizable = true; checkForFalse = (expression.Operator == Operator.EqualEqualEqual); } else if ((literalExpression.Value is string) && ((string)literalExpression.Value == String.Empty)) { optimizable = true; checkForFalse = (expression.Operator == Operator.EqualEqualEqual); } if (optimizable) { bool parenthesize = false; writer.Write(checkForFalse ? "!" : "!!"); if ((expression.LeftOperand.Parenthesized == false) && ((expression.LeftOperand.Type == ExpressionType.Binary) || (expression.LeftOperand.Type == ExpressionType.Conditional) || (expression.LeftOperand.Type == ExpressionType.InlineScript))) { parenthesize = true; writer.Write("("); } GenerateExpression(generator, symbol, expression.LeftOperand); if (parenthesize) { writer.Write(")"); } return; } } } GenerateExpression(generator, symbol, expression.LeftOperand); writer.WriteTrimmed(OperatorConverter.OperatorToString(expression.Operator)); GenerateExpression(generator, symbol, expression.RightOperand); }
private static void GenerateThisExpression(ScriptGenerator generator, MemberSymbol symbol, ThisExpression expression) { ScriptTextWriter writer = generator.Writer; writer.Write("this"); }
public static void GenerateExpression(ScriptGenerator generator, MemberSymbol symbol, Expression expression) { ScriptTextWriter writer = generator.Writer; if (expression.Parenthesized) { writer.Write("("); } switch (expression.Type) { case ExpressionType.Literal: GenerateLiteralExpression(generator, symbol, (LiteralExpression)expression); break; case ExpressionType.Local: GenerateLocalExpression(generator, symbol, (LocalExpression)expression); break; case ExpressionType.Member: Debug.Fail("MemberExpression missed from conversion to higher level expression."); break; case ExpressionType.Field: GenerateFieldExpression(generator, symbol, (FieldExpression)expression); break; case ExpressionType.EnumerationField: GenerateEnumerationFieldExpression(generator, symbol, (EnumerationFieldExpression)expression); break; case ExpressionType.PropertyGet: GeneratePropertyExpression(generator, symbol, (PropertyExpression)expression); break; case ExpressionType.PropertySet: Debug.Fail("PropertyExpression(set) should be covered as part of BinaryExpression logic."); break; case ExpressionType.MethodInvoke: case ExpressionType.DelegateInvoke: GenerateMethodExpression(generator, symbol, (MethodExpression)expression); break; case ExpressionType.BaseInitializer: GenerateBaseInitializerExpression(generator, symbol, (BaseInitializerExpression)expression); break; case ExpressionType.EventAdd: case ExpressionType.EventRemove: GenerateEventExpression(generator, symbol, (EventExpression)expression); break; case ExpressionType.Indexer: GenerateIndexerExpression(generator, symbol, (IndexerExpression)expression); break; case ExpressionType.This: GenerateThisExpression(generator, symbol, (ThisExpression)expression); break; case ExpressionType.Base: Debug.Fail("BaseExpression not handled by container expression."); break; case ExpressionType.New: GenerateNewExpression(generator, symbol, (NewExpression)expression); break; case ExpressionType.Unary: GenerateUnaryExpression(generator, symbol, (UnaryExpression)expression); break; case ExpressionType.Binary: GenerateBinaryExpression(generator, symbol, (BinaryExpression)expression); break; case ExpressionType.Conditional: GenerateConditionalExpression(generator, symbol, (ConditionalExpression)expression); break; case ExpressionType.Type: GenerateTypeExpression(generator, symbol, (TypeExpression)expression); break; case ExpressionType.Delegate: GenerateDelegateExpression(generator, symbol, (DelegateExpression)expression); break; case ExpressionType.LateBound: GenerateLateBoundExpression(generator, symbol, (LateBoundExpression)expression); break; case ExpressionType.InlineScript: GenerateInlineScriptExpression(generator, symbol, (InlineScriptExpression)expression); break; default: Debug.Fail("Unexpected expression type: " + expression.Type); break; } if (expression.Parenthesized) { writer.Write(")"); } }
private static void GenerateUnaryExpression(ScriptGenerator generator, MemberSymbol symbol, UnaryExpression expression) { ScriptTextWriter writer = generator.Writer; PropertyExpression propExpression = expression.Operand as PropertyExpression; if ((propExpression != null) && ((expression.Operator == Operator.PreIncrement) || (expression.Operator == Operator.PostIncrement) || (expression.Operator == Operator.PreDecrement) || (expression.Operator == Operator.PostDecrement))) { Debug.Assert(propExpression.Type == ExpressionType.PropertyGet); string fudgeOperator; GenerateExpression(generator, symbol, propExpression.ObjectReference); writer.Write(".set_"); writer.Write(propExpression.Property.GeneratedName); writer.Write("("); GenerateExpression(generator, symbol, propExpression.ObjectReference); writer.Write(".get_"); writer.Write(propExpression.Property.GeneratedName); writer.Write("()"); if ((expression.Operator == Operator.PreIncrement) || (expression.Operator == Operator.PostIncrement)) { writer.WriteTrimmed(" + "); fudgeOperator = " - "; } else { writer.WriteTrimmed(" - "); fudgeOperator = " + "; } writer.Write("1"); writer.Write(")"); if ((expression.Operator == Operator.PreIncrement) || (expression.Operator == Operator.PreDecrement)) { writer.WriteTrimmed(fudgeOperator); writer.Write("1"); } return; } if ((expression.Operator == Operator.PreIncrement) || (expression.Operator == Operator.PreDecrement)) { ExpressionGenerator.GenerateExpression(generator, symbol, expression.Operand); writer.Write(OperatorConverter.OperatorToString(expression.Operator)); } else { writer.Write(OperatorConverter.OperatorToString(expression.Operator)); ExpressionGenerator.GenerateExpression(generator, symbol, expression.Operand); } }
private static void GenerateConditionalExpression(ScriptGenerator generator, MemberSymbol symbol, ConditionalExpression expression) { ScriptTextWriter writer = generator.Writer; if (expression.Condition.Parenthesized == false) { writer.Write("("); } ExpressionGenerator.GenerateExpression(generator, symbol, expression.Condition); if (expression.Condition.Parenthesized == false) { writer.Write(")"); } writer.WriteTrimmed(" ? "); ExpressionGenerator.GenerateExpression(generator, symbol, expression.TrueValue); writer.WriteTrimmed(" : "); ExpressionGenerator.GenerateExpression(generator, symbol, expression.FalseValue); }
public ParameterSymbol(string name, MemberSymbol parent, TypeSymbol valueType, ParameterMode mode) : base(SymbolType.Parameter, name, parent, valueType) { _mode = mode; }
private static void GenerateDelegateExpression(ScriptGenerator generator, MemberSymbol symbol, DelegateExpression expression) { ScriptTextWriter writer = generator.Writer; bool createDelegate = false; if ((expression.Method.Visibility & MemberVisibility.Static) == 0) { createDelegate = true; writer.Write("ss.Delegate.create("); ExpressionGenerator.GenerateExpression(generator, symbol, expression.ObjectReference); writer.WriteTrimmed(", "); } AnonymousMethodSymbol anonymousMethod = expression.Method as AnonymousMethodSymbol; if (anonymousMethod == null) { // TODO: This probably needs to handle global method roots... if (expression.Method.IsGlobalMethod == false) { ExpressionGenerator.GenerateExpression(generator, symbol, expression.ObjectReference); writer.Write("."); } writer.Write(expression.Method.GeneratedName); } else { writer.Write("function("); if ((anonymousMethod.Parameters != null) && (anonymousMethod.Parameters.Count != 0)) { bool obfuscateParams = generator.Options.Minimize; string obfuscationPrefix = null; int paramIndex = 0; foreach (ParameterSymbol parameterSymbol in anonymousMethod.Parameters) { if (paramIndex > 0) { writer.WriteTrimmed(", "); } if (obfuscateParams) { if (paramIndex == 0) { obfuscationPrefix = "$p" + anonymousMethod.Depth.ToString(CultureInfo.InvariantCulture) + "_"; } parameterSymbol.SetTransformedName(obfuscationPrefix + paramIndex); } writer.Write(parameterSymbol.GeneratedName); paramIndex++; } } writer.Write(")"); writer.WriteTrimmed(" {"); writer.WriteLine(); writer.Indent++; CodeGenerator.GenerateScript(generator, anonymousMethod); writer.Indent--; writer.Write("}"); } if (createDelegate) { writer.Write(")"); } }