From 4dc2462b3c31fbe3b300882e60e5ccbd9e370c6c Mon Sep 17 00:00:00 2001 From: Mikhail Velikanov Date: Mon, 26 Sep 2022 17:43:36 +0300 Subject: [PATCH] Fix syntax around generic types and class instance creation expression. Change-Id: I661f1f4edfa0ea4514c483de2b745d93b0a1c856 Signed-off-by: Mikhail Velikanov --- .../com/ohos/migrator/AbstractTranspiler.java | 2 +- .../ohos/migrator/java/JavaTransformer.java | 173 ++++++++++-------- .../ohos/migrator/staticTS/NodeBuilder.java | 161 +++++++++++++++- .../migrator/staticTS/parser/StaticTSLexer.g4 | 1 - .../staticTS/parser/StaticTSParser.g4 | 22 ++- .../staticTS/parser/StaticTSParserBase.java | 1 - .../staticTS/writer/StaticTSWriter.java | 145 +++++++++------ .../java/class_instance_creation.java.sts | 4 +- migrator/test/java/generic_class_2.java | 4 +- migrator/test/java/generic_class_2.java.sts | 6 +- migrator/test/java/generic_class_4.java.sts | 2 +- .../test/java/generic_interface_1.java.sts | 4 +- migrator/test/java/inferred_types.java.sts | 17 +- migrator/test/java/literals.java.sts | 4 +- migrator/test/java/method_references.java.sts | 2 +- migrator/test/java/named_types.java.sts | 6 +- migrator/test/java/npe_in_type_argument.java | 31 ++++ .../test/java/npe_in_type_argument.java.sts | 36 ++++ .../java/npe_in_type_parameter_bound.java.sts | 2 +- migrator/test/java/npe_in_wildcard_bound.java | 1 + .../test/java/npe_in_wildcard_bound.java.sts | 5 +- 21 files changed, 456 insertions(+), 173 deletions(-) create mode 100644 migrator/test/java/npe_in_type_argument.java create mode 100755 migrator/test/java/npe_in_type_argument.java.sts diff --git a/migrator/src/com/ohos/migrator/AbstractTranspiler.java b/migrator/src/com/ohos/migrator/AbstractTranspiler.java index 2d65f7b24..2cc14383f 100644 --- a/migrator/src/com/ohos/migrator/AbstractTranspiler.java +++ b/migrator/src/com/ohos/migrator/AbstractTranspiler.java @@ -85,7 +85,7 @@ public abstract class AbstractTranspiler implements Transpiler { File outFile = new File(srcFile.getPath() + Main.STS_EXT); if (outDir != null) outFile = new File(outDir, outFile.getName()); - StaticTSWriter writer = new StaticTSWriter(new FileWriter(outFile.getPath())); + StaticTSWriter writer = new StaticTSWriter(outFile.getPath()); writer.visit(stsCU); writer.close(); diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index bf5b8d622..4f4b3b720 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -708,16 +708,16 @@ public class JavaTransformer extends ASTVisitor implements Transformer { if (isIntersectionTypeBound) pushCurrent(new IntersectionTypeContext(stsCurrent, 0)); for (Type javaTypeBound : javaTypeBounds) { - if (isTypeReference(javaTypeBound)) { + if (NodeBuilder.isTypeReference(javaTypeBound)) { javaTypeBound.accept(this); } else { // Only type references are allowed as type parameter bounds // (or as intersection type components) in STS. // Warn and emit __UnknownType__ with original source code as comment. - reportError("Invalid type " + javaTypeBound.toString() + " in type parameter bound", javaTypeBound); - stsCurrent.addChild(NodeBuilder.typeReference("__UnknownType__")).setParent(stsCurrent); - stsCurrent.addChild(NodeBuilder.multiLineComment("/* " + javaTypeBound.toString() + " */")); + String boundTypeName = javaTypeBound.toString(); + reportError("Invalid type " + boundTypeName + " in type parameter bound", javaTypeBound); + stsCurrent.addChild(NodeBuilder.unknownTypeReference(boundTypeName)).setParent(stsCurrent); } } @@ -728,11 +728,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popCurrent(); // TypeParameterContext return false; } - - private boolean isTypeReference(Type javaType) { - return javaType.isSimpleType() || javaType.isQualifiedType() || - javaType.isNameQualifiedType() || javaType.isParameterizedType(); - } private ParserRuleContext createDeclarationOrMemberContextWithAccessModifier(int javaMods) { boolean isInClassContext = stsCurrent instanceof ClassBodyContext; boolean isInInterfaceContext = stsCurrent instanceof InterfaceBodyContext; @@ -981,17 +976,22 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // SimpleType: { Annotation } TypeName // // STS tree: - // primaryType: typeReference or plain typeReference (depending on context) - // typeReference: typeReferencePart ('.' typeReferencePart)* - // where typeReferencePart: qualifiedName typeArguments? + // typeReference or + // primaryType: typeReference (depending on context), + // where typeReference: typeReferencePart ('.' typeReferencePart)* + // and typeReferencePart: qualifiedName typeArguments? @Override public boolean visit(SimpleType javaSimpleType) { boolean needPrimaryType = isInPrimaryTypeContext(); if (needPrimaryType) pushCurrent(new PrimaryTypeContext(stsCurrent, 0)); String typeFQN = javaSimpleType.getName().getFullyQualifiedName(); - stsCurrent.addChild(NodeBuilder.typeReference(typeFQN)).setParent(stsCurrent); + TypeReferenceContext stsTypeRef = NodeBuilder.typeReference(typeFQN); + + // Add empty type arguments list if this is a raw type + NodeBuilder.addEmptyTypeArgumentsToRawType(stsTypeRef, javaSimpleType); + stsCurrent.addChild(stsTypeRef).setParent(stsCurrent); if (needPrimaryType) popCurrent(); // PrimaryTypeContext typeTransformed.add(javaSimpleType); @@ -1029,6 +1029,9 @@ public class JavaTransformer extends ASTVisitor implements Transformer { TypeReferencePartContext stsTypeRefPart = NodeBuilder.typeReferencePart(typeName); stsTypeRef.addChild(stsTypeRefPart).setParent(stsTypeRef); + // Add empty type arguments list if this is a raw type + NodeBuilder.addEmptyTypeArgumentsToRawType(stsTypeRef, javaQualifiedType); + if (needPrimaryType) popCurrent(); // PrimaryTypeContext typeTransformed.add(javaQualifiedType); @@ -1051,8 +1054,11 @@ public class JavaTransformer extends ASTVisitor implements Transformer { String javaQualifierText = javaNameQualifiedType.getQualifier().getFullyQualifiedName(); String typeFQN = javaQualifierText + '.' + javaNameQualifiedType.getName().getFullyQualifiedName(); TypeReferenceContext stsType = NodeBuilder.typeReference(typeFQN); - stsCurrent.addChild(stsType).setParent(stsCurrent); + // Add empty type arguments list if this is a raw type + NodeBuilder.addEmptyTypeArgumentsToRawType(stsType, javaNameQualifiedType); + + stsCurrent.addChild(stsType).setParent(stsCurrent); if (needPrimaryType) popCurrent(); // PrimaryTypeContext typeTransformed.add(javaNameQualifiedType); @@ -1067,24 +1073,37 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // Translate the type part of parameterized type. // This should create TypeReference context with // one or several TypeReferencePart nodes under it. - javaParametrizedType.getType().accept(this); + Type javaGenericType = javaParametrizedType.getType(); + if (NodeBuilder.isTypeReference(javaGenericType)) { + javaGenericType.accept(this); + } + else { + String javaGenericTypeName = javaGenericType.toString(); + reportError("Invalid generic type " + javaGenericTypeName + " in parametrized type", javaParametrizedType); + stsCurrent.addChild(NodeBuilder.unknownTypeReference(javaGenericTypeName)).setParent(stsCurrent); + } + + // Get last TypeReferencePartContext node of the + // TypeReferenceContext node we just constructed above + ParseTree stsLastChild = stsCurrent.getChild(stsCurrent.getChildCount() - 1); + stsLastChild = stsLastChild.getChild(stsLastChild.getChildCount() - 1); + // Translate and add type arguments to last TypeReferencePartContext node + pushCurrent((TypeReferencePartContext)stsLastChild, false); List javaTypeArgs = javaParametrizedType.typeArguments(); if (javaTypeArgs != null && !javaTypeArgs.isEmpty()) { - // Add type arguments to the last TypeReferencePart node of TypeReference - // context that we just constructed by translating the type part above. - ParseTree lastChild = stsCurrent.getChild(stsCurrent.getChildCount() - 1); - assert(lastChild instanceof TypeReferenceContext); - pushCurrent((TypeReferenceContext)lastChild, false); - lastChild = stsCurrent.getChild(stsCurrent.getChildCount() - 1); - assert(lastChild instanceof TypeReferencePartContext && lastChild.getChildCount() == 1); - pushCurrent((TypeReferencePartContext)lastChild, false); - translateTypeArguments(javaTypeArgs); - - popCurrent(); // (TypeReferencePartContext)lastChild - popCurrent(); // (TypeReferenceContext)lastChild } + else { + // Handle the case of Java "diamond" syntax, e.g. new HashSet<>() + ITypeBinding javaTypeBinding = NodeBuilder.getTypeBinding(javaParametrizedType); + if (javaTypeBinding != null && !javaTypeBinding.isRecovered()) { + ITypeBinding[] javaTypeArgBindings = javaTypeBinding.getTypeArguments(); + TypeArgumentsContext stsTypeArgs = NodeBuilder.translateTypeArguments(javaTypeArgBindings); + stsCurrent.addChild(stsTypeArgs).setParent(stsCurrent); + } + } + popCurrent(); // (TypeReferencePartContext)stsLastChild if (needPrimaryType) popCurrent(); // PrimaryTypeContext @@ -1098,24 +1117,24 @@ public class JavaTransformer extends ASTVisitor implements Transformer { Type javaBound = javaWildcardType.getBound(); if (javaBound != null) { - pushCurrent(new WildcardBoundContext(stsCurrent, 0)); - // Add corresponding keyword and bounding type - int stsTerminalType = javaWildcardType.isUpperBound() ? StaticTSParser.Extends : StaticTSParser.Super; - stsCurrent.addChild(NodeBuilder.terminalNode(stsTerminalType)); + String stsInOrOutKeyword = javaWildcardType.isUpperBound() ? StaticTSParser.OUT : StaticTSParser.IN; + stsCurrent.addChild(NodeBuilder.terminalIdentifier(stsInOrOutKeyword)); - if (isTypeReference(javaBound)) { + if (NodeBuilder.isTypeReference(javaBound)) { javaBound.accept(this); } else { // Only type references are allowed as wildcard bounds in STS. // Warn and emit __UnknownType__ with original source code as a comment. - reportError("Invalid type " + javaBound.toString() + " in wildcard type bound", javaBound); - stsCurrent.addChild(NodeBuilder.typeReference("__UnknownType__")).setParent(stsCurrent); - stsCurrent.addChild(NodeBuilder.multiLineComment("/* " + javaBound.toString() + " */")); + String boundTypeName = javaBound.toString(); + reportError("Invalid bound type " + boundTypeName + " in wildcard type", javaBound); + stsCurrent.addChild(NodeBuilder.unknownTypeReference(boundTypeName)).setParent(stsCurrent); } - - popCurrent(); // WildcardBoundContext + } + else { + // No wildcard bound, i.e. '?' in Java translates to 'out' in STS + stsCurrent.addChild(NodeBuilder.terminalIdentifier(StaticTSParser.OUT)); } popCurrent(); // WildcardTypeContext @@ -1165,33 +1184,22 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return false; } - private void translateType(ITypeBinding javaType, ASTNode javaNode) { + private void translateTypeBinding(ITypeBinding javaType, ASTNode javaNode) { if (javaType == null || javaType.isRecovered()) { // Warn and emit __UnknownType__ as result type - String message = String.format("Unrecognized type %s", javaType != null ? javaType.getName() : ""); - reportError(message, javaNode); + String typeName = javaType != null ? javaType.getName() : ""; + reportError("Failed to resolve type " + typeName, javaNode); stsCurrent.addChild(NodeBuilder.unknownTypeAnnotation(javaType)).setParent(stsCurrent); + return; } - else { - // NOTE: Method "ITypeBinding.getQualifiedName()" constructs fully-qualified name - // of the corresponding type, including its generic part, array brackets, etc., - // and returns it as a string value. Using this method, we can avoid constructing - // entire STS tree for the corresponding type, simply making an identifier token - // with string value of type's fully-qualified name and wrapping it with a single - // TypeReferenceContext node. - // - // See the following link for details: - // https://help.eclipse.org/latest/topic/org.eclipse.jdt.doc.isv/reference/api/org/eclipse/jdt/core/dom/ITypeBinding.html#getQualifiedName() - pushCurrent(new TypeAnnotationContext(stsCurrent, 0)); - pushCurrent(new PrimaryTypeContext(stsCurrent, 0)); - TypeReferenceContext stsTypeRef = NodeBuilder.typeReference(javaType.getQualifiedName()); - stsCurrent.addChild(stsTypeRef).setParent(stsCurrent); + pushCurrent(new TypeAnnotationContext(stsCurrent, 0)); + pushCurrent(new PrimaryTypeContext(stsCurrent, 0)); - popCurrent(); // PrimaryTypeContext - popCurrent(); // TypeAnnotationContext - } + stsCurrent.addChild(NodeBuilder.translateTypeBinding(javaType)); + popCurrent(); // PrimaryTypeContext + popCurrent(); // TypeAnnotationContext } // Java tree: @@ -1564,12 +1572,21 @@ public class JavaTransformer extends ASTVisitor implements Transformer { for (Type javaTypeArg : javaTypeArgs) { pushCurrent(new TypeArgumentContext(stsCurrent, 0)); - javaTypeArg.accept(this); + + if (NodeBuilder.isTypeArgument(javaTypeArg)) { + javaTypeArg.accept(this); + } else { + String javaTypeArgName = javaTypeArg.toString(); + reportError("Invalid type argument " + javaTypeArgName, javaTypeArg); + TypeReferenceContext stsTypeArg = NodeBuilder.unknownTypeReference(javaTypeArgName); + stsCurrent.addChild(stsTypeArg).setParent(stsCurrent); + } + popCurrent(); // TypeArgumentContext } - popCurrent(); // TypeArgumentList - popCurrent(); // TypeArguments + popCurrent(); // TypeArgumentListContext + popCurrent(); // TypeArgumentsContext } } @@ -1868,7 +1885,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { IVariableBinding variableBinding = javaVariableDeclarationFragment.resolveBinding(); if (variableBinding != null) { - translateType(variableBinding.getType(), javaVariableDeclarationFragment); + translateTypeBinding(variableBinding.getType(), javaVariableDeclarationFragment); } else { // Warn and emit __UnknownType__ as variable type @@ -2257,7 +2274,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // Add initializer to constant declaration context pushCurrent(new InitializerContext(stsCurrent, 0)); - pushCurrent(new NewClassExpressionContext(pushSingleExpression())); + pushCurrent(new NewClassInstanceExpressionContext(pushSingleExpression())); stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.New)); stsCurrent.addChild(NodeBuilder.typeReference(javaEnumTypeName)).setParent(stsCurrent); @@ -2283,7 +2300,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { javaEnumConstClassBody.accept(this); } - popSingleExpression(); // NewClassExpressionContext + popSingleExpression(); // NewClassInstanceExpressionContext popCurrent(); // InitializerContext popCurrent(); // ConstantDeclarationContext @@ -3022,14 +3039,18 @@ public class JavaTransformer extends ASTVisitor implements Transformer { stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Try)); } - pushCurrent(new NewClassExpressionContext(pushSingleExpression())); - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.New)).setParent(stsCurrent); - - translateTypeArguments(javaClassInstanceCreation.typeArguments()); - // Add outer class object, if any. Expression javaOuterObject = javaClassInstanceCreation.getExpression(); - if (javaOuterObject != null) javaOuterObject.accept(this); + if (javaOuterObject != null) { + pushCurrent(new NewInnerClassInstanceExpressionContext(pushSingleExpression())); + javaOuterObject.accept(this); + } + else { + pushCurrent(new NewClassInstanceExpressionContext(pushSingleExpression())); + } + + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.New)).setParent(stsCurrent); + translateTypeArguments(javaClassInstanceCreation.typeArguments()); javaClassInstanceCreation.getType().accept(this); @@ -3040,7 +3061,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { javaAnonymousClassDeclaration.accept(this); } - popSingleExpression(); // NewClassExpressionContext + popSingleExpression(); // NewInnerClassInstanceExpressionContext or NewClassInstanceExpressionContext if (ctorCanThrow) { popSingleExpression(); // TryExpressionContext @@ -3777,7 +3798,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { } if (lambdaMethod != null) { - translateType(lambdaMethod.getReturnType(), javaLambdaExpr); + translateTypeBinding(lambdaMethod.getReturnType(), javaLambdaExpr); if(checkThrownExceptionSet(javaLambdaExpr)) addMultipleThrownExceptions(lambdaMethod.getExceptionTypes()); } @@ -3814,7 +3835,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { private void createMethodRefLambdaParam(ITypeBinding paramType, int lambdaParamIdx, MethodReference javaMethodRef) { pushCurrent(new ParameterContext(stsCurrent, 0)); stsCurrent.addChild(NodeBuilder.terminalIdentifier(METHOD_REF_PARAM_PREFIX + lambdaParamIdx)); - translateType(paramType, javaMethodRef); + translateTypeBinding(paramType, javaMethodRef); popCurrent(); // ParameterContext } @@ -3844,7 +3865,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { ITypeBinding returnType = javaMethodBinding.isConstructor() ? javaMethodBinding.getDeclaringClass() : javaMethodBinding.getReturnType(); - translateType(returnType, javaMethodRef); + translateTypeBinding(returnType, javaMethodRef); stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Arrow)); @@ -3953,7 +3974,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Try)); } - pushCurrent(new NewClassExpressionContext(pushSingleExpression())); + pushCurrent(new NewClassInstanceExpressionContext(pushSingleExpression())); stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.New)).setParent(stsCurrent); translateTypeArguments(javaCreationRef.typeArguments()); @@ -3962,7 +3983,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { createMethodRefCallArgs(javaCtorBinding.getParameterTypes().length, 1); - popSingleExpression(); // NewClassExpressionContext + popSingleExpression(); // NewClassInstanceExpressionContext if (ctorCanThrow) { popSingleExpression(); // TryExpressionContext @@ -4388,7 +4409,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // Emit 'recover' keyword instead of 'catch' if // exception type is a subtype of RuntimeException. - ITypeBinding javaExcTypeBinding = javaExceptionType.resolveBinding(); + ITypeBinding javaExcTypeBinding = NodeBuilder.getTypeBinding(javaExceptionType); int termCode = isRuntimeExceptionType(javaExcTypeBinding) ? StaticTSParser.Recover : StaticTSParser.Catch; stsCurrent.addChild(NodeBuilder.terminalNode(termCode)); diff --git a/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java b/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java index f5d173cb9..70c2e6ead 100644 --- a/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java +++ b/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java @@ -26,7 +26,7 @@ import org.eclipse.jdt.core.dom.*; public class NodeBuilder { private static final Vocabulary vocabulary = StaticTSParser.VOCABULARY; - + private static final String UNKNOWN_TYPE_NAME = "__UnknownType__"; public static TerminalNode terminalNode(int type) { return new TerminalNodeImpl(new CommonToken(type, stsName(type))); } @@ -96,6 +96,32 @@ public class NodeBuilder { return stsTypeNameCode; } + private static int stsTypeNameCode(String typeName) { + int stsTypeNameCode = -1; + + if ("boolean".equals(typeName)) + stsTypeNameCode = StaticTSParser.Boolean; + else if ("byte".equals(typeName)) + stsTypeNameCode = StaticTSParser.Byte; + else if ("char".equals(typeName)) + stsTypeNameCode = StaticTSParser.Char; + else if ("int".equals(typeName)) + stsTypeNameCode = StaticTSParser.Int; + else if ("double".equals(typeName)) + stsTypeNameCode = StaticTSParser.Double; + else if ("float".equals(typeName)) + stsTypeNameCode = StaticTSParser.Float; + else if ("long".equals(typeName)) + stsTypeNameCode = StaticTSParser.Long; + else if ("short".equals(typeName)) + stsTypeNameCode = StaticTSParser.Short; + else if ("void".equals(typeName)) + stsTypeNameCode = StaticTSParser.Void; + else + assert false : "Unknown type"; + + return stsTypeNameCode; + } public static PredefinedTypeContext predefinedType(PrimitiveType.Code javaPrimitiveTypeCode) { // predefinedType -> TerminalNode PredefinedTypeContext stsPredefinedType = new PredefinedTypeContext(null, 0); @@ -103,6 +129,12 @@ public class NodeBuilder { return stsPredefinedType; } + public static PredefinedTypeContext predefinedType(String typeName) { + // predefinedType -> TerminalNode + PredefinedTypeContext stsPredefinedType = new PredefinedTypeContext(null, 0); + stsPredefinedType.addChild(terminalNode(stsTypeNameCode(typeName))); + return stsPredefinedType; + } public static AccessibilityModifierContext accessibilityModifier(int javaModifiers) { int stsModifierCode = -1; if ((javaModifiers & Modifier.PRIVATE) != 0) @@ -257,6 +289,12 @@ public class NodeBuilder { return stsTypeReference; } + public static TypeReferenceContext unknownTypeReference(String comment) { + String typeName = UNKNOWN_TYPE_NAME; + if (comment != null) typeName += " /* " + comment + " */"; + return typeReference(typeName); + } + public static AssignmentOperatorContext assignmentOperator(Assignment.Operator javaAssignOp) { int stsOperatorCode = -1; @@ -328,8 +366,12 @@ public class NodeBuilder { } public static ArrayTypeContext arrayType(String elementTypeName, int dimensions) { + return arrayType(typeReference(elementTypeName), dimensions); + } + + public static ArrayTypeContext arrayType(ParserRuleContext elementType, int dimensions) { ArrayTypeContext stsArrayType = new ArrayTypeContext(null, 0); - stsArrayType.addChild(typeReference(elementTypeName)).setParent(stsArrayType); + stsArrayType.addChild(elementType).setParent(stsArrayType); for (int i = 0; i < dimensions; ++i) { stsArrayType.addChild(terminalNode(StaticTSParser.OpenBracket)); stsArrayType.addChild(terminalNode(StaticTSParser.CloseBracket)); @@ -396,7 +438,7 @@ public class NodeBuilder { } public static TypeAnnotationContext unknownTypeAnnotation() { - return typeAnnotation("__UnknownType__"); + return typeAnnotation(UNKNOWN_TYPE_NAME); } public static TypeAnnotationContext unknownTypeAnnotation(Type javaType) { @@ -536,4 +578,117 @@ public class NodeBuilder { return stsSingleExpr; } + + public static ParserRuleContext translateTypeBinding(ITypeBinding javaType) { + if (javaType.isPrimitive()) { + return predefinedType(javaType.getName()); + } + + if (javaType.isArray()) { + ITypeBinding javaArrayElemType = javaType.getElementType(); + ParserRuleContext stsArrayElemType = translateTypeBinding(javaArrayElemType); + return arrayType(stsArrayElemType, javaType.getDimensions()); + } + + if (javaType.isParameterizedType()) { + ITypeBinding javaErasedType = javaType.getErasure(); + ParserRuleContext stsType = translateTypeBinding(javaErasedType); + if (stsType.getRuleIndex() != StaticTSParser.RULE_typeReference) { + stsType = unknownTypeReference(javaErasedType.getQualifiedName()); + } + + // Translate type arguments and inject them into last child of TypeReferenceContext node + TypeReferencePartContext stsLastTypePart = (TypeReferencePartContext)stsType.getChild(stsType.getChildCount()-1); + TypeArgumentsContext stsTypeArgs = translateTypeArguments(javaType.getTypeArguments()); + stsLastTypePart.addChild(stsTypeArgs).setParent(stsLastTypePart); + return stsType; + } + + if (javaType.isWildcardType()) { + WildcardTypeContext stsWildCardType = new WildcardTypeContext(null, 0); + ITypeBinding javaBoundType = javaType.getBound(); + if (javaBoundType != null) { + String stsInOrOutKeyword = javaType.isUpperbound() ? StaticTSParser.OUT : StaticTSParser.IN; + stsWildCardType.addChild(terminalIdentifier(stsInOrOutKeyword)); + ParserRuleContext stsBoundType = translateTypeBinding(javaBoundType); + stsWildCardType.addChild(stsBoundType).setParent(stsWildCardType); + } + else { + stsWildCardType.addChild(terminalIdentifier(StaticTSParser.OUT)); + } + return stsWildCardType; + } + + if (javaType.isIntersectionType()) { + IntersectionTypeContext stsIntersectionType = new IntersectionTypeContext(null, 0); + for (ITypeBinding javaIntersectedType : javaType.getTypeBounds()) { + ParserRuleContext stsIntersectedType = translateTypeBinding(javaIntersectedType); + stsIntersectionType.addChild(stsIntersectedType).setParent(stsIntersectionType); + } + return stsIntersectionType; + } + + // All other types should be named - just emit TypeReferenceContext + TypeReferenceContext stsTypeRef = typeReference(javaType.getQualifiedName()); + addEmptyTypeArgumentsToRawType(stsTypeRef, javaType); + return stsTypeRef; + } + + public static void addEmptyTypeArgumentsToRawType(TypeReferenceContext stsTypeRef, ITypeBinding javaTypeBinding) { + if (javaTypeBinding != null && javaTypeBinding.isRawType()) { + TypeReferencePartContext stsLastTypePart = (TypeReferencePartContext) stsTypeRef.getChild(stsTypeRef.getChildCount() - 1); + stsLastTypePart.addChild(new TypeArgumentsContext(stsLastTypePart, 0)).setParent(stsLastTypePart); + } + } + public static void addEmptyTypeArgumentsToRawType(TypeReferenceContext stsTypeRef, Type javaType) { + ITypeBinding javaTypeBinding = getTypeBinding(javaType); + addEmptyTypeArgumentsToRawType(stsTypeRef, javaTypeBinding); + } + public static TypeArgumentsContext translateTypeArguments(ITypeBinding[] javaTypeArgs) { + TypeArgumentsContext stsTypeArgs = new TypeArgumentsContext(null, 0); + + if (javaTypeArgs != null) { + TypeArgumentListContext stsTypeArgList = new TypeArgumentListContext(stsTypeArgs, 0); + stsTypeArgs.addChild(stsTypeArgList).setParent(stsTypeArgs); + + for (ITypeBinding javaTypeArg : javaTypeArgs) { + ParserRuleContext stsTypeArg = translateTypeBinding(javaTypeArg); + if (!isTypeArgument(stsTypeArg)) stsTypeArg = unknownTypeReference(null); + + TypeArgumentContext stsTypeArgNode = new TypeArgumentContext(stsTypeArgList, 0); + stsTypeArgNode.addChild(stsTypeArg).setParent(stsTypeArgNode); + stsTypeArgList.addChild(stsTypeArgNode).setParent(stsTypeArgList); + } + } + + return stsTypeArgs; + } + + public static boolean isTypeArgument(ParserRuleContext stsType) { + return stsType.getRuleIndex() == StaticTSParser.RULE_arrayType || + stsType.getRuleIndex() == StaticTSParser.RULE_typeReference || + stsType.getRuleIndex() == StaticTSParser.RULE_wildcardType; + } + + public static boolean isTypeArgument(Type javaType) { + return isTypeReference(javaType) || javaType.isArrayType() || javaType.isWildcardType(); + } + + public static boolean isTypeReference(Type javaType) { + return javaType.isSimpleType() || javaType.isQualifiedType() || + javaType.isNameQualifiedType() || javaType.isParameterizedType(); + } + + public static ITypeBinding getTypeBinding(Type javaType) { + // Type.resolveBinding() can throw exceptions, so let's catch them + ITypeBinding javaTypeBinding; + try { + javaTypeBinding = javaType.resolveBinding(); + } + catch (Exception e) { + javaTypeBinding = null; + } + + return javaTypeBinding; + } } diff --git a/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSLexer.g4 b/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSLexer.g4 index 75be039e9..dd16f0e07 100644 --- a/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSLexer.g4 +++ b/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSLexer.g4 @@ -171,7 +171,6 @@ Char: 'char'; Void: 'void'; /// Identifier Names and Identifiers - Identifier: IdentifierStart IdentifierPart*; /// String Literals diff --git a/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 b/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 index 7b455b61b..c6caa6833 100644 --- a/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 +++ b/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 @@ -49,6 +49,13 @@ options { superClass=StaticTSParserBase; } +@members { + // These are context-dependent keywords, i.e. those that + // can't be used as identifiers only in specific contexts + public static final String IN = "in"; // keyword in type argument and type parameter contexts + public static final String OUT = "out"; // keyword in type argument and type parameter contexts +} + compilationUnit : packageDeclaration? importDeclaration* topDeclaration* EOF ; @@ -287,7 +294,7 @@ typeParameterList ; typeParameter - : Identifier constraint? + : ({ this.next(IN) || this.next(OUT) }? Identifier)? Identifier constraint? ; constraint @@ -309,11 +316,8 @@ typeArgument ; wildcardType - : QuestionMark wildcardBound? - ; - -wildcardBound - : (Extends | Super) typeReference + : { this.next(IN) }? Identifier typeReference + | { this.next(OUT) }? Identifier typeReference? ; // Statements @@ -426,7 +430,8 @@ singleExpression : OpenParen parameterList? CloseParen typeAnnotation Arrow lambdaBody # LambdaExpression | singleExpression indexExpression # ArrayAccessExpression | singleExpression Dot Identifier # MemberAccessExpression - | New typeArguments? (singleExpression Dot)? typeReference arguments? classBody? # NewClassExpression + | New typeArguments? typeReference arguments? classBody? # NewClassInstanceExpression + | singleExpression Dot New typeArguments? typeReference arguments? classBody? # NewInnerClassInstanceExpression | New primaryType indexExpression+ (OpenBracket CloseBracket)* # NewArrayExpression | singleExpression typeArguments? arguments # CallExpression | singleExpression {this.notLineTerminator()}? PlusPlus # PostIncrementExpression @@ -440,7 +445,8 @@ singleExpression | singleExpression (Multiply | Divide | Modulus) singleExpression # MultiplicativeExpression | singleExpression (Plus | Minus) singleExpression # AdditiveExpression | singleExpression shiftOperator singleExpression # BitShiftExpression - | singleExpression (LessThan | MoreThan | LessThanEquals | GreaterThanEquals) singleExpression # RelationalExpression + | singleExpression (LessThan | MoreThan | + LessThanEquals | GreaterThanEquals) singleExpression # RelationalExpression | singleExpression Instanceof primaryType # InstanceofExpression | singleExpression (Equals | NotEquals) singleExpression # EqualityExpression | singleExpression BitAnd singleExpression # BitAndExpression diff --git a/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParserBase.java b/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParserBase.java index 6798b6c7e..2426e9c10 100644 --- a/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParserBase.java +++ b/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParserBase.java @@ -63,7 +63,6 @@ public abstract class StaticTSParserBase extends Parser int nextTokenType = _input.LT(1).getType(); return nextTokenType != StaticTSParser.OpenBrace && nextTokenType != StaticTSParser.Function; } - protected boolean closeBrace() { return _input.LT(1).getType() == StaticTSParser.CloseBrace; } diff --git a/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java b/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java index 0971c642f..125f03a9f 100644 --- a/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java +++ b/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java @@ -15,6 +15,8 @@ package com.ohos.migrator.staticTS.writer; +import com.ohos.migrator.Main; +import com.ohos.migrator.ResultCode; import com.ohos.migrator.staticTS.parser.StaticTSLexer; import com.ohos.migrator.staticTS.parser.StaticTSParser; import com.ohos.migrator.staticTS.parser.StaticTSParser.*; @@ -33,14 +35,15 @@ import java.util.List; public class StaticTSWriter extends StaticTSParserBaseVisitor { private final Writer out; + private final String outPath; private final String indentStep = " "; // 4 spaces private final StringBuffer sb = new StringBuffer(); private String indentCurrent = ""; - public StaticTSWriter(Writer w) { - out = w; + public StaticTSWriter(String path) throws IOException { + outPath = path; + out = new FileWriter(path); } - public void close() { if (out != null) { try { @@ -65,7 +68,7 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { if (args.length >= 2) { try { - StaticTSWriter writer = new StaticTSWriter(new FileWriter(args[1])); + StaticTSWriter writer = new StaticTSWriter(args[1]); writer.visit(compilationUnit); writer.close(); } catch (IOException e) { @@ -138,11 +141,26 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { return null; } - // typeParameter: Identifier constraint? | typeParameters; + // typeParameter: ({ this.next(IN) || this.next(OUT) }? Identifier)? Identifier constraint? @Override public Void visitTypeParameter(TypeParameterContext stsTypeParameter) { - TerminalNode termIdentifier = stsTypeParameter.Identifier(); - sb.append(termIdentifier.getText()); + List stsIdentifiers = stsTypeParameter.Identifier(); + + if (stsIdentifiers.size() > 1) { + // Sanity check: First identifier should be either 'in' or 'out' + String stsInOrOutKeyword = stsIdentifiers.get(0).getText(); + if (!StaticTSParser.IN.equals(stsInOrOutKeyword) && !StaticTSParser.OUT.equals(stsInOrOutKeyword)) { + reportError("Unexpected token " + stsInOrOutKeyword + " in type parameter", stsTypeParameter); + stsInOrOutKeyword = "/* Unexpected token: " + stsInOrOutKeyword + " */"; + } + + sb.append(stsInOrOutKeyword).append(' '); + sb.append(stsIdentifiers.get(1).getText()); + } + else { + sb.append(stsIdentifiers.get(0).getText()); + } + ConstraintContext stsConstraint = stsTypeParameter.constraint(); if (stsConstraint != null) { sb.append(' '); @@ -225,38 +243,30 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { return null; } - // wildcardType: QuestionMark wildcardBound? + // wildcardType: { this.next(IN) }? Identifier typeReference | { this.next(OUT) }? Identifier typeReference? @Override public Void visitWildcardType(WildcardTypeContext stsWildcardType) { - sb.append('?'); + // Sanity check: Leading identifier should be either 'in' or 'out' + String stsIdentifier = stsWildcardType.Identifier().getText(); + if (!StaticTSParser.IN.equals(stsIdentifier) && !StaticTSParser.OUT.equals(stsIdentifier)) { + reportError("Unexpected token " + stsIdentifier + " in wildcard type", stsWildcardType); + stsIdentifier = "/* Unexpected token: " + stsIdentifier + " */"; + } + + sb.append(stsIdentifier); - WildcardBoundContext stsWildcardBound = stsWildcardType.wildcardBound(); - if (stsWildcardBound != null) { + TypeReferenceContext stsTypeRef = stsWildcardType.typeReference(); + if (stsTypeRef != null) { sb.append(' '); - visitWildcardBound(stsWildcardBound); + visitTypeReference(stsTypeRef); } return null; } - // wildcardBound: (Extends | Super) typeReference - @Override - public Void visitWildcardBound(WildcardBoundContext stsWildcardBound) { - TerminalNode term = stsWildcardBound.Extends(); - if (term == null) term = stsWildcardBound.Super(); - - assert(term != null); - sb.append(term.getText()).append(' '); - - TypeReferenceContext stsTypeRef = stsWildcardBound.typeReference(); - assert(stsTypeRef != null); - visitTypeReference(stsTypeRef); - - // We may have added a comment here if type reference was invalid. - // See JavaTransformer.visit(WildcardType) for details. - visitComment(stsWildcardBound, 2); - - return null; + private void reportError(String message, ParserRuleContext stsNode) { + String loc = outPath + ":" + stsNode.getStart().getLine(); + Main.addError(ResultCode.TranspileError, message + " at " + loc); } @Override @@ -281,7 +291,7 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { return null; } - // typeReference: typeReferencePard (Dot typeReferencePart)? + // typeReference: typeReferencePart (Dot typeReferencePart)? @Override public Void visitTypeReference(TypeReferenceContext stsTypeReference) { List stsTypeParts = stsTypeReference.typeReferencePart(); @@ -293,14 +303,14 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { return null; } - // typeReferencePart: qualifiedNmae typeArguments? + // typeReferencePart: qualifiedName typeArguments? @Override public Void visitTypeReferencePart(TypeReferencePartContext stsTypeReferencePart) { visitQualifiedName(stsTypeReferencePart.qualifiedName()); - TypeArgumentsContext ststTypeArguments = stsTypeReferencePart.typeArguments(); - if (ststTypeArguments != null) { - visitTypeArguments(ststTypeArguments); + TypeArgumentsContext stsTypeArguments = stsTypeReferencePart.typeArguments(); + if (stsTypeArguments != null) { + visitTypeArguments(stsTypeArguments); } return null; @@ -743,23 +753,23 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { } // importDeclaration: Import qualifiedName (Dot Multiply)? SemiColon? - public Void visitImportDeclaration(ImportDeclarationContext stsImportDeclatation) { + public Void visitImportDeclaration(ImportDeclarationContext stsImportDeclaration) { doNeededIndent(); - sb.append(stsImportDeclatation.Import().getText()).append(' '); + sb.append(stsImportDeclaration.Import().getText()).append(' '); - visitQualifiedName(stsImportDeclatation.qualifiedName()); + visitQualifiedName(stsImportDeclaration.qualifiedName()); - TerminalNode termDot = stsImportDeclatation.Dot(); - TerminalNode termAs = stsImportDeclatation.As(); + TerminalNode termDot = stsImportDeclaration.Dot(); + TerminalNode termAs = stsImportDeclaration.As(); if (termDot != null) { sb.append(termDot.getText()); - TerminalNode termMult = stsImportDeclatation.Multiply(); + TerminalNode termMult = stsImportDeclaration.Multiply(); assert(termMult != null); sb.append(termMult.getText()); } else if (termAs != null) { sb.append(' ').append(termAs.getText()).append(' '); - TerminalNode termId = stsImportDeclatation.Identifier(); + TerminalNode termId = stsImportDeclaration.Identifier(); assert(termId != null); sb.append(termId.getText()); } @@ -1092,7 +1102,7 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { return null; } - // | (typereference Dot)? Super # SuperExpression + // | (typeReference Dot)? Super # SuperExpression @Override public Void visitSuperExpression(SuperExpressionContext stsSuperExpression) { TypeReferenceContext stsTypeReference = stsSuperExpression.typeReference(); @@ -1345,8 +1355,9 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { indentDecrement(); sb.append(indentCurrent).append("}"); - // Don't start new line if this class body is a part of a object creation expression - if (!(stsClassBody.getParent() instanceof NewClassExpressionContext)) + // Don't start new line if this class body is a part of an object creation expression + if (!(stsClassBody.getParent() instanceof NewClassInstanceExpressionContext) && + !(stsClassBody.getParent() instanceof NewInnerClassInstanceExpressionContext)) sb.append("\n\n"); return null; @@ -1492,7 +1503,7 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { return null; } - // | OpenBracked expressionSequence? CloseBracket #ArrayLiterlaExpression + // | OpenBracket expressionSequence? CloseBracket #ArrayLiterlaExpression @Override public Void visitArrayLiteralExpression(ArrayLiteralExpressionContext stsArrayLiteral) { sb.append('['); @@ -1610,28 +1621,48 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { return null; } - // | New typeArguments? (singleExpression Dot)? typeReference arguments? classBody? # NewClassExpression + // | New typeArguments? typeReference arguments? classBody? # NewClassInstanceExpression @Override - public Void visitNewClassExpression(NewClassExpressionContext stsNewClassExpression) { - sb.append(stsNewClassExpression.New().getText()).append(' '); + public Void visitNewClassInstanceExpression(NewClassInstanceExpressionContext stsNewClassInstanceExpression) { + sb.append(stsNewClassInstanceExpression.New().getText()).append(' '); - TypeArgumentsContext stsTypeArguments = stsNewClassExpression.typeArguments(); + TypeArgumentsContext stsTypeArguments = stsNewClassInstanceExpression.typeArguments(); if (stsTypeArguments != null) visitTypeArguments(stsTypeArguments); - SingleExpressionContext stsOuterObject = stsNewClassExpression.singleExpression(); - if (stsOuterObject != null) { - stsOuterObject.accept(this); - sb.append('.'); + visitTypeReference(stsNewClassInstanceExpression.typeReference()); + + ArgumentsContext stsArguments = stsNewClassInstanceExpression.arguments(); + if (stsArguments != null) { + visitArguments(stsArguments); + } + + ClassBodyContext stsClassBody = stsNewClassInstanceExpression.classBody(); + if (stsClassBody != null) { + visitClassBody(stsClassBody); } - visitTypeReference(stsNewClassExpression.typeReference()); + return null; + } + + // | singleExpression Dot New typeArguments? typeReference arguments? classBody? # NewInnerClassInstanceExpression + @Override + public Void visitNewInnerClassInstanceExpression(NewInnerClassInstanceExpressionContext stsNewInnerClassInstanceExpression) { + SingleExpressionContext stsOuterObject = stsNewInnerClassInstanceExpression.singleExpression(); + stsOuterObject.accept(this); + + sb.append('.').append(stsNewInnerClassInstanceExpression.New().getText()).append(' '); + + TypeArgumentsContext stsTypeArguments = stsNewInnerClassInstanceExpression.typeArguments(); + if (stsTypeArguments != null) visitTypeArguments(stsTypeArguments); + + visitTypeReference(stsNewInnerClassInstanceExpression.typeReference()); - ArgumentsContext stsArguments = stsNewClassExpression.arguments(); + ArgumentsContext stsArguments = stsNewInnerClassInstanceExpression.arguments(); if (stsArguments != null) { visitArguments(stsArguments); } - ClassBodyContext stsClassBody = stsNewClassExpression.classBody(); + ClassBodyContext stsClassBody = stsNewInnerClassInstanceExpression.classBody(); if (stsClassBody != null) { visitClassBody(stsClassBody); } diff --git a/migrator/test/java/class_instance_creation.java.sts b/migrator/test/java/class_instance_creation.java.sts index fcd50901c..a3fe1f61d 100644 --- a/migrator/test/java/class_instance_creation.java.sts +++ b/migrator/test/java/class_instance_creation.java.sts @@ -43,8 +43,8 @@ open class class_instance_creation { } inner_inst1 : inner = new inner(1); - inner_inst2 : inner = new inst1.inner(2); - inner_inst3 : inner = new inst4.inner(3) { + inner_inst2 : inner = inst1.new inner(2); + inner_inst3 : inner = inst4.new inner(3) { private s : String ; public open bar(): void { s = "bar"; diff --git a/migrator/test/java/generic_class_2.java b/migrator/test/java/generic_class_2.java index 6959f15b3..f941da515 100644 --- a/migrator/test/java/generic_class_2.java +++ b/migrator/test/java/generic_class_2.java @@ -49,9 +49,9 @@ class Pair { class Test { public static void main(String[] args) { - Seq strs = new Seq("a", new Seq("b", new Seq())); + Seq strs = new Seq<>("a", new Seq("b", new Seq())); Seq nums = new Seq(new Integer(1), new Seq(new Double(1.5), new Seq())); Seq.Zipper zipper = strs.new Zipper(); Seq> combined = zipper.zip(nums); } -} \ No newline at end of file +} diff --git a/migrator/test/java/generic_class_2.java.sts b/migrator/test/java/generic_class_2.java.sts index 2837a5960..085637ec7 100644 --- a/migrator/test/java/generic_class_2.java.sts +++ b/migrator/test/java/generic_class_2.java.sts @@ -35,7 +35,7 @@ open class Seq { return new Seq>(); } else { - let tailZipper : Seq.Zipper = new tail.Zipper(); + let tailZipper : Seq.Zipper = tail.new Zipper(); return new Seq>(new Pair(head, that.head), tailZipper.zip(that.tail)); } } @@ -55,9 +55,9 @@ open class Pair { open class Test { public static main(args : String[]): void { - let strs : Seq = new Seq("a", new Seq("b", new Seq())); + let strs : Seq = new Seq("a", new Seq("b", new Seq())); let nums : Seq = new Seq(new Integer(1), new Seq(new Double(1.5), new Seq())); - let zipper : Seq.Zipper = new strs.Zipper(); + let zipper : Seq.Zipper = strs.new Zipper(); let combined : Seq> = zipper.zip(nums); } } diff --git a/migrator/test/java/generic_class_4.java.sts b/migrator/test/java/generic_class_4.java.sts index ebec1d974..cf2e51d96 100644 --- a/migrator/test/java/generic_class_4.java.sts +++ b/migrator/test/java/generic_class_4.java.sts @@ -16,7 +16,7 @@ package com.ohos.migrator.test.java; open class test_generic { - open choose(b : boolean, c1 : Class, c2 : Class): Class { + open choose(b : boolean, c1 : Class, c2 : Class): Class { return b ? c1 : c2; } } diff --git a/migrator/test/java/generic_interface_1.java.sts b/migrator/test/java/generic_interface_1.java.sts index 867ca6aa4..f0ebc7f76 100644 --- a/migrator/test/java/generic_interface_1.java.sts +++ b/migrator/test/java/generic_interface_1.java.sts @@ -16,10 +16,10 @@ package com.ohos.migrator.test.java; interface J { - m(c : Class): S ; + m(c : Class): S ; } interface K { - m(c : Class): T ; + m(c : Class): T ; } diff --git a/migrator/test/java/inferred_types.java.sts b/migrator/test/java/inferred_types.java.sts index eea79cb1d..6cbc8e19c 100644 --- a/migrator/test/java/inferred_types.java.sts +++ b/migrator/test/java/inferred_types.java.sts @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.ohos.migrator.tests.java; import java.util.List; @@ -48,11 +49,11 @@ open class Main { } interface IParametrizedTypes { - M(list : List, listOfArrays : List, listOfLists : List>[]): List ; + M(list : List, listOfArrays : List, listOfLists : List>[]): List<> ; } interface IWildcards { - M(listExtends : List, listSuper : List): List ; + M(listExtends : List, listSuper : List): List ; } interface IGeneric { @@ -78,13 +79,13 @@ open class Main { ; let l2 : IClassTypes = (c : com.ohos.migrator.tests.java.Main.C, s : java.lang.String, e : com.ohos.migrator.tests.java.Main.E): com.ohos.migrator.tests.java.Main.IPrimitiveTypes =>l1; let l3 : IArrays = (sArray : java.lang.String[], iArray : com.ohos.migrator.tests.java.Main.IPrimitiveTypes[][], eArray : com.ohos.migrator.tests.java.Main.E[][]): int[] =>new int[5]; - let l4 : IParametrizedTypes = (list : java.util.List, listOfArrays : java.util.List, ListOfLists : java.util.List>[]): java.util.List =>list; - let l5 : IWildcards = (listExtends : java.util.List, listSuper : java.util.List): java.util.List =>listExtends; + let l4 : IParametrizedTypes = (list : java.util.List, listOfArrays : java.util.List, ListOfLists : java.util.List>[]): java.util.List<> =>list; + let l5 : IWildcards = (listExtends : java.util.List, listSuper : java.util.List): java.util.List =>listExtends; let l6 : IGeneric = (list : java.util.List): java.lang.Number =>list.get(0); - let l7 : IGeneric = (list : java.util.List): java.lang.Object =>list.get(0); - let l8 : IGeneric = (list : java.util.List): java.lang.Number =>list.get(0); - let l9 : IGeneric = (list : java.util.List): java.lang.Number =>list.get(0); + let l7 : IGeneric = (list : java.util.List): java.lang.Object =>list.get(0); + let l8 : IGeneric = (list : java.util.List): java.lang.Number =>list.get(0); + let l9 : IGeneric = (list : java.util.List): java.lang.Number =>list.get(0); let l10 : IInnerOuter = (inner : com.ohos.migrator.tests.java.Main.OuterClass>.InnerClass): int =>0; } } - \ No newline at end of file + diff --git a/migrator/test/java/literals.java.sts b/migrator/test/java/literals.java.sts index 3e3d7934d..9d7f26e56 100755 --- a/migrator/test/java/literals.java.sts +++ b/migrator/test/java/literals.java.sts @@ -42,9 +42,9 @@ open class literals { let tl : boolean = true; let fl : boolean = false; let cl : Class = literals.class; - let ll : Class = long.class; + let ll : Class = long.class; let sal : Class = String[].class; - let dal : Class = double[].class; + let dal : Class = double[].class; } } diff --git a/migrator/test/java/method_references.java.sts b/migrator/test/java/method_references.java.sts index 8bba70d10..8c031b37c 100644 --- a/migrator/test/java/method_references.java.sts +++ b/migrator/test/java/method_references.java.sts @@ -93,7 +93,7 @@ open class MethodReferencesExamples { let person3 : Person = myApp.factory((__migrator_lambda_param_1 : int, __migrator_lambda_param_2 : java.lang.String): com.ohos.migrator.tests.java.MethodReferencesExamples.Person =>new Person(__migrator_lambda_param_1, __migrator_lambda_param_2), 40, "Peter"); let cons1 : Consumer = (__migrator_lambda_param_1 : com.ohos.migrator.tests.java.MethodReferencesExamples.A.B): void =>__migrator_lambda_param_1.foo(); let cons2 : Consumer = (__migrator_lambda_param_1 : java.lang.String): void =>A.B.bar(__migrator_lambda_param_1); - let generic : BiConsumer = (__migrator_lambda_param_1 : com.ohos.migrator.tests.java.MethodReferencesExamples.Generic, __migrator_lambda_param_2 : java.lang.Integer): void =>__migrator_lambda_param_1.bar(__migrator_lambda_param_2); + let generic : BiConsumer, Integer> = (__migrator_lambda_param_1 : com.ohos.migrator.tests.java.MethodReferencesExamples.Generic, __migrator_lambda_param_2 : java.lang.Integer): void =>__migrator_lambda_param_1.bar(__migrator_lambda_param_2); let getLength : Function0 = (): int =>"sleeping".length(); let length : int = getLength.apply(); let persons : Person[] = new Person[5]; diff --git a/migrator/test/java/named_types.java.sts b/migrator/test/java/named_types.java.sts index bf7e15d13..f28a77dc9 100644 --- a/migrator/test/java/named_types.java.sts +++ b/migrator/test/java/named_types.java.sts @@ -29,7 +29,7 @@ open class named_types { } open class auxilliary { - public open foo(): named_types.inner { + public open foo(): named_types.inner<> { return null; } @@ -37,11 +37,11 @@ open class auxilliary { return null; } - public open foobar(arg : named_types.inner): named_types.inner { + public open foobar(arg : named_types.inner): named_types.inner { return null; } - public open barfoo(arg : named_types.inner): named_types.inner { + public open barfoo(arg : named_types.inner): named_types.inner { return null; } } diff --git a/migrator/test/java/npe_in_type_argument.java b/migrator/test/java/npe_in_type_argument.java new file mode 100644 index 000000000..137706326 --- /dev/null +++ b/migrator/test/java/npe_in_type_argument.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ohos.migrator.test.java; + +class A {} + +interface I {} + +interface I2 { + int getInt(); +} + +class npe_in_type_argument { + int i = new I2<>() { + int f = 10; + public int getInt() { return f; } + }.getInt(); +} diff --git a/migrator/test/java/npe_in_type_argument.java.sts b/migrator/test/java/npe_in_type_argument.java.sts new file mode 100755 index 000000000..81d66ca0d --- /dev/null +++ b/migrator/test/java/npe_in_type_argument.java.sts @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ohos.migrator.test.java; + +open class A { +} + +interface I { +} + +interface I2 { + getInt(): int ; +} + +open class npe_in_type_argument { + i : int = new I2<__UnknownType__>() { + f : int = 10; + public override getInt(): int { + return f; + } + }.getInt(); +} + diff --git a/migrator/test/java/npe_in_type_parameter_bound.java.sts b/migrator/test/java/npe_in_type_parameter_bound.java.sts index d69eaf574..c2e6955aa 100644 --- a/migrator/test/java/npe_in_type_parameter_bound.java.sts +++ b/migrator/test/java/npe_in_type_parameter_bound.java.sts @@ -15,5 +15,5 @@ package com.ohos.migrator.test.java; -open class npe_in_type_parameter_bound { +open class npe_in_type_parameter_bound { } diff --git a/migrator/test/java/npe_in_wildcard_bound.java b/migrator/test/java/npe_in_wildcard_bound.java index cb5e17247..83d0a95ca 100644 --- a/migrator/test/java/npe_in_wildcard_bound.java +++ b/migrator/test/java/npe_in_wildcard_bound.java @@ -17,4 +17,5 @@ package com.ohos.migrator.test.java; class npe_in_wildcard_bound { Class test() { return null; } + public static int foo(Class> classDescr) { return 0; } } diff --git a/migrator/test/java/npe_in_wildcard_bound.java.sts b/migrator/test/java/npe_in_wildcard_bound.java.sts index bd4353f41..f54c0d697 100644 --- a/migrator/test/java/npe_in_wildcard_bound.java.sts +++ b/migrator/test/java/npe_in_wildcard_bound.java.sts @@ -16,7 +16,10 @@ package com.ohos.migrator.test.java; open class npe_in_wildcard_bound { - open test(): Class { + open test(): Class { return null; } + public static foo(classDescr : Class>): int { + return 0; + } } -- Gitee