public static void Go(ScalaWriter writer, CastExpressionSyntax expression) { var model = Program.GetModel(expression); var symbol = model.GetSymbolInfo(expression); var castingFrom = model.GetTypeInfo(expression.Expression).Type; if (castingFrom == null) { castingFrom = model.GetTypeInfo(expression).Type; } var srcTypeScala = TypeProcessor.ConvertType((ITypeSymbol)castingFrom); var destType = model.GetTypeInfo(expression.Type).Type; var destTypeScala = TypeProcessor.TryConvertType(expression.Type); if (destTypeScala == srcTypeScala) { //Eat casts where the types are identical. Enums getting casted to int fall here, and since we use ints to represent enums anyway, it's not necessary. Core.Write(writer, expression.Expression); } else if (symbol.Symbol != null && srcTypeScala != "Int" && srcTypeScala != "String" && srcTypeScala != "Bool") { //when the symbol is non-null, this indicates we're calling a cast operator function writer.Write(TypeProcessor.ConvertType(symbol.Symbol.ContainingType)); writer.Write(".op_Explicit_"); writer.Write(destTypeScala.TrySubstringBeforeFirst('[').Replace('.', '_')); writer.Write("("); Core.Write(writer, expression.Expression); writer.Write(")"); } else if (TypeProcessor.IsPrimitiveType(srcTypeScala) && TypeProcessor.IsPrimitiveType(destTypeScala)) { if (srcTypeScala == "Byte") { //JVM's bytes are signed, so we must take care when upcasting writer.Write("System.CsScala.ByteTo"); writer.Write(destTypeScala); writer.Write("("); Core.Write(writer, expression.Expression); writer.Write(")"); } else { //Casting between primitives is handled in scala bo the .toXX functions Core.Write(writer, expression.Expression); writer.Write(".to"); writer.Write(destTypeScala); } } else { Core.Write(writer, expression.Expression); writer.Write(".asInstanceOf["); writer.Write(destTypeScala); writer.Write("]"); } }
public static void Go(ScalaWriter writer, MemberAccessExpressionSyntax expression) { var model = Program.GetModel(expression); var memberName = expression.Name.Identifier.ValueText; var type = model.GetTypeInfo(expression.Expression).ConvertedType; var typeStr = TypeProcessor.GenericTypeName(type); if (expression.Expression is PredefinedTypeSyntax) { if (memberName == "MaxValue" || memberName == "MinValue" || memberName == "NaN") { var predefined = expression.Expression.ToString(); if (predefined.StartsWith("u")) { //Scala does not have unsigned types. Forward these to CsScala writer.Write("System.CsScala."); writer.Write(predefined); writer.Write(memberName); } else { writer.Write(predefined[0].ToString().ToUpper()); writer.Write(predefined.Substring(1)); writer.Write("."); writer.Write(memberName); } } else { var field = System.Type.GetType(typeStr).GetField(memberName); if (field == null) { throw new Exception("Cannot use " + memberName + " as a field. If you're passing a function, wrap a closure around it. " + Utility.Descriptor(expression)); } var val = field.GetValue(null); if (val is string) { writer.Write("\"" + val + "\""); } else { writer.Write(val.ToString()); } } } else if (type.OriginalDefinition is INamedTypeSymbol && type.OriginalDefinition.As <INamedTypeSymbol>().SpecialType == SpecialType.System_Nullable_T) { switch (memberName) { case "HasValue": writer.Write("("); WriteMember(writer, expression.Expression); writer.Write(" != null)"); break; case "Value": var nullableType = TypeProcessor.ConvertType(type.As <INamedTypeSymbol>().TypeArguments.Single()); WriteMember(writer, expression.Expression); if (TypeProcessor.IsPrimitiveType(nullableType)) { writer.Write("."); writer.Write(nullableType[0].ToString().ToLower()); writer.Write(nullableType.Substring(1)); writer.Write("Value()"); } break; default: throw new Exception("Need handler for Nullable." + memberName + " " + Utility.Descriptor(expression)); } } else { var translate = PropertyTranslation.Get(typeStr, memberName); if (translate != null && translate.ExtensionMethod != null) { writer.Write(translate.ExtensionMethod); writer.Write("("); if (!(model.GetSymbolInfo(expression.Expression).Symbol is INamedTypeSymbol)) { Core.Write(writer, expression.Expression); } writer.Write(")"); return; } if (translate != null) { memberName = translate.ReplaceWith; } else { memberName = WriteIdentifierName.TransformIdentifier(memberName); } if (type != null) //if type is null, then we're just a namespace. We can ignore these. { WriteMember(writer, expression.Expression); writer.Write("."); } writer.Write(memberName); if (expression.Name is GenericNameSyntax) { var gen = expression.Name.As <GenericNameSyntax>(); writer.Write("["); bool first = true; foreach (var g in gen.TypeArgumentList.Arguments) { if (first) { first = false; } else { writer.Write(", "); } writer.Write(TypeProcessor.ConvertTypeWithColon(g)); } writer.Write("]"); } } }