private JsArrayLiteral mapArrayLit(Node node) throws JsParserException { JsArrayLiteral toLit = new JsArrayLiteral(); Node from = node.getFirstChild(); while (from != null) { toLit.getExpressions().add(mapExpression(from)); from = from.getNext(); } return toLit; }
/** @return a JsArrayLiteral listing the type arguments for the interface instance. */ private JsExpression buildTypeArgsForFactory( FunctionType functionType, InterfaceType instanceType, List<? extends Type> listTypeVars, JsExpression contextTypeArgs) { if (functionType.getTypeVariables().size() == 0) { return null; } if (instanceType.hasDynamicTypeArgs()) { return translationContext.getProgram().getNullLiteral(); } JsArrayLiteral arr = new JsArrayLiteral(); for (Type type : instanceType.getArguments()) { JsExpression typeExpr = buildTypeLookupExpression(type, listTypeVars, contextTypeArgs); arr.getExpressions().add(typeExpr); } return arr; }
/** @return a JsArrayLiteral listing the type arguments for the interface instance. */ private JsExpression buildTypeArgs( InterfaceType instanceType, List<? extends Type> listTypeVars, JsExpression contextTypeArgs) { ClassElement classElement = instanceType.getElement(); if (!hasTypeParameters(classElement)) { return null; } if (instanceType.hasDynamicTypeArgs()) { JsProgram program = translationContext.getProgram(); return program.getNullLiteral(); } JsArrayLiteral arr = new JsArrayLiteral(); assert instanceType.getArguments().size() > 0; for (Type type : instanceType.getArguments()) { JsExpression typeExpr = buildTypeLookupExpression(type, listTypeVars, contextTypeArgs); arr.getExpressions().add(typeExpr); } return arr; }
/** @return js The expression used to lookup the RTT for the given type. */ private JsExpression buildTypeLookupExpression( Type type, List<? extends Type> list, JsExpression contextTypeArgs) { switch (TypeKind.of(type)) { case INTERFACE: InterfaceType interfaceType = (InterfaceType) type; JsInvocation callLookup = call(null, getRTTLookupMethodName(interfaceType.getElement())); if (hasTypeParameters(interfaceType.getElement()) && !interfaceType.hasDynamicTypeArgs()) { JsArrayLiteral typeArgs = new JsArrayLiteral(); for (Type arg : interfaceType.getArguments()) { typeArgs.getExpressions().add(buildTypeLookupExpression(arg, list, contextTypeArgs)); } callLookup.getArguments().add(typeArgs); } return callLookup; case FUNCTION_ALIAS: // TODO(johnlenz): implement this return newQualifiedNameRef("RTT.placeholderType"); case VARIABLE: TypeVariable var = (TypeVariable) type; JsProgram program = translationContext.getProgram(); int varIndex = 0; for (Type t : list) { if (t.equals(type)) { return call( null, newQualifiedNameRef("RTT.getTypeArg"), Cloner.clone(contextTypeArgs), program.getNumberLiteral(varIndex)); } varIndex++; } throw new AssertionError("unresolved type variable:" + var); default: throw new AssertionError("unexpected type kind:" + type.getKind()); } }
private void generateRTTAddToMethod(DartClass x) { ClassElement classElement = x.getSymbol(); // 2) create "addTo" method // Foo$Type$addTo(target, typeargs) { // var rtt = Foo$lookupOrCreateRTT(typeargs) // target.implementedTypes[rtt.classkey] = rtt; // } // Build the function JsFunction addToFn = new JsFunction(globalScope); addToFn.setBody(new JsBlock()); JsScope scope = new JsScope(globalScope, "temp"); JsName targetType = scope.declareName("target"); addToFn.getParameters().add(new JsParameter(targetType)); // Get the RTT info object JsName rtt = scope.declareName("rtt"); List<JsStatement> body = addToFn.getBody().getStatements(); JsInvocation callLookup = newInvocation(getRTTLookupMethodName(classElement)); if (hasTypeParameters(classElement)) { JsName typeArgs = scope.declareName("typeArgs"); addToFn.getParameters().add(new JsParameter(typeArgs)); callLookup.getArguments().add(new JsNameRef(typeArgs)); } JsStatement rttLookup = newVar((SourceInfo) null, rtt, callLookup); body.add(rttLookup); // store it. JsExpression addToTypes = newAssignment( new JsArrayAccess( newNameRef(targetType.makeRef(), "implementedTypes"), newNameRef(rtt.makeRef(), "classKey")), rtt.makeRef()); body.add(addToTypes.makeStmt()); InterfaceType superType = classElement.getSupertype(); if (superType != null && !superType.getElement().isObject()) { ClassElement interfaceElement = superType.getElement(); JsInvocation callAddTo = newInvocation(getRTTAddToMethodName(interfaceElement), targetType.makeRef()); if (hasTypeParameters(interfaceElement) && !superType.hasDynamicTypeArgs()) { JsArrayLiteral superTypeArgs = new JsArrayLiteral(); List<? extends Type> typeParams = classElement.getTypeParameters(); for (Type arg : superType.getArguments()) { superTypeArgs .getExpressions() .add( buildTypeLookupExpression( arg, typeParams, nameref(null, targetType.makeRef(), "typeArgs"))); } callAddTo.getArguments().add(superTypeArgs); } body.add(callAddTo.makeStmt()); } // Add the interfaces for (InterfaceType interfaceType : classElement.getInterfaces()) { ClassElement interfaceElement = interfaceType.getElement(); JsInvocation callAddTo = call(null, getRTTAddToMethodName(interfaceElement), targetType.makeRef()); if (hasTypeParameters(interfaceElement) && !interfaceType.hasDynamicTypeArgs()) { JsArrayLiteral interfaceTypeArgs = new JsArrayLiteral(); List<? extends Type> typeParams = classElement.getTypeParameters(); for (Type arg : interfaceType.getArguments()) { interfaceTypeArgs .getExpressions() .add( buildTypeLookupExpression( arg, typeParams, nameref(null, targetType.makeRef(), "typeArgs"))); } callAddTo.getArguments().add(interfaceTypeArgs); } body.add(callAddTo.makeStmt()); } // Add the function statement JsExpression fnDecl = newAssignment(getRTTAddToMethodName(classElement), addToFn); globalBlock.getStatements().add(fnDecl.makeStmt()); }
@NotNull private static List<JsExpression> wrapInArrayLiteral(@NotNull List<JsExpression> translatedArgs) { JsArrayLiteral argsWrappedInArray = new JsArrayLiteral(); argsWrappedInArray.getExpressions().addAll(translatedArgs); return Arrays.<JsExpression>asList(argsWrappedInArray); }