blob: 39da324cb5afd5c6fe479eccb4e1c3391767bc39 [file] [log] [blame]
/*
* Copyright (C) 2013 The Android Open Source Project
*
* 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.android.jack.jayce.v0002.nodes;
import com.android.jack.ir.SourceInfo;
import com.android.jack.ir.ast.JAbstractMethodBody;
import com.android.jack.ir.ast.JDefinedClassOrInterface;
import com.android.jack.ir.ast.JMethod;
import com.android.jack.ir.ast.JMethodId;
import com.android.jack.ir.ast.JParameter;
import com.android.jack.ir.ast.JSession;
import com.android.jack.ir.ast.MethodKind;
import com.android.jack.jayce.JayceClassOrInterfaceLoader;
import com.android.jack.jayce.JayceMethodLoader;
import com.android.jack.jayce.MethodNode;
import com.android.jack.jayce.NodeLevel;
import com.android.jack.jayce.v0002.NNode;
import com.android.jack.jayce.v0002.io.ExportSession;
import com.android.jack.jayce.v0002.io.ImportHelper;
import com.android.jack.jayce.v0002.io.JayceInternalReaderImpl;
import com.android.jack.jayce.v0002.io.JayceInternalWriterImpl;
import com.android.jack.jayce.v0002.io.Token;
import java.io.IOException;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
/**
* A Java method representation.
*/
public class NMethod extends NNode implements HasSourceInfo, MethodNode {
@Nonnull
public static final Token TOKEN = Token.METHOD;
@CheckForNull
public String name;
@CheckForNull
public String returnType;
@Nonnull
public List<NParameter> parameters = Collections.emptyList();
@CheckForNull
public MethodKind methodKind;
@Nonnull
public List<String> thrownExceptions = Collections.emptyList();
public int modifier;
@Nonnull
public List<NAnnotationLiteral> annotations = Collections.emptyList();
@CheckForNull
public NAbstractMethodBody body;
@Nonnull
public List<NMarker> markers = Collections.emptyList();
@CheckForNull
public NSourceInfo sourceInfo;
@CheckForNull
protected NodeLevel level;
@Override
@Nonnull
public NodeLevel getLevel() {
assert level != null;
return level;
}
@Override
public void importFromJast(@Nonnull ImportHelper loader, @Nonnull Object jElement) {
JMethod jMethod = (JMethod) jElement;
name = jMethod.getName();
returnType = ImportHelper.getSignatureName(jMethod.getType());
parameters = loader.load(NParameter.class, jMethod.getParams());
methodKind = jMethod.getMethodId().getKind();
thrownExceptions = ImportHelper.getSignatureNameList(jMethod.getThrownExceptions());
modifier = jMethod.getModifier();
annotations = loader.load(NAnnotationLiteral.class, jMethod.getAnnotations());
body = (NAbstractMethodBody) loader.load(jMethod.getBody());
markers = loader.load(NMarker.class, jMethod.getAllMarkers());
sourceInfo = loader.load(jMethod.getSourceInfo());
}
@Override
@Nonnull
public JMethod exportAsJast(@Nonnull ExportSession exportSession) {
throw new UnsupportedOperationException();
}
@Nonnull
public JMethod exportAsJast(@Nonnull ExportSession exportSession,
@Nonnull JayceClassOrInterfaceLoader enclosingLoader) {
assert name != null;
assert returnType != null;
assert methodKind != null;
assert sourceInfo != null;
SourceInfo info = sourceInfo.exportAsJast(exportSession);
JDefinedClassOrInterface enclosingType = exportSession.getCurrentType();
assert enclosingType != null;
JMethodId id = new JMethodId(name, methodKind);
JMethod jMethod = new JMethod(
info, id, enclosingType,
exportSession.getLookup().getType(returnType),
modifier, new JayceMethodLoader(this, enclosingLoader));
exportSession.setCurrentMethod(jMethod);
for (NParameter parameter : parameters) {
JParameter jParam = parameter.exportAsJast(exportSession);
jMethod.addParam(jParam);
id.addParam(jParam.getType());
}
for (String exceptionName : thrownExceptions) {
jMethod.addThrownException(exportSession.getLookup().getClass(exceptionName));
}
for (NAnnotationLiteral annotationLiteral : annotations) {
jMethod.addAnnotation(annotationLiteral.exportAsJast(exportSession));
}
if (body != null && exportSession.getNodeLevel() == NodeLevel.FULL) {
jMethod.setBody(body.exportAsJast(exportSession));
}
for (NMarker marker : markers) {
jMethod.addMarker(marker.exportAsJast(exportSession));
}
clearBodyResolvers(exportSession);
return jMethod;
}
@CheckForNull
@Override
public JAbstractMethodBody loadBody(@Nonnull JMethod method) {
if (body != null) {
JSession session = method.getParent(JSession.class);
ExportSession exportSession = new ExportSession(session.getPhantomLookup(), session,
NodeLevel.FULL);
exportSession.setCurrentMethod(method);
Iterator<JParameter> iter = method.getParams().iterator();
for (NParameter parameter : parameters) {
assert parameter.id != null;
exportSession.getParameterResolver().addTarget(parameter.id, iter.next());
}
JAbstractMethodBody jBody = body.exportAsJast(exportSession);
method.setBody(jBody);
clearBodyResolvers(exportSession);
return jBody;
}
return null;
}
@Override
public void writeContent(@Nonnull JayceInternalWriterImpl out) throws IOException {
assert methodKind != null;
out.writeId(name);
out.writeId(returnType);
out.writeNodes(parameters);
out.writeMethodKindEnum(methodKind);
out.writeIds(thrownExceptions);
out.writeInt(modifier);
out.writeNodes(annotations);
out.writeNode(body);
out.writeNodes(markers);
}
@Override
public void readContent(@Nonnull JayceInternalReaderImpl in) throws IOException {
level = in.getNodeLevel();
name = in.readId();
returnType = in.readId();
parameters = in.readNodes(NParameter.class);
methodKind = in.readMethodKindEnum();
thrownExceptions = in.readIds();
modifier = in.readInt();
annotations = in.readNodes(NAnnotationLiteral.class);
body = in.readNode(NAbstractMethodBody.class);
markers = in.readNodes(NMarker.class);
}
@Override
@Nonnull
public Token getToken() {
return TOKEN;
}
@Override
@Nonnull
public NSourceInfo getSourceInfos() {
assert sourceInfo != null;
return sourceInfo;
}
@Override
public void setSourceInfos(@Nonnull NSourceInfo sourceInfo) {
this.sourceInfo = sourceInfo;
}
protected static void clearBodyResolvers(ExportSession exportSession) {
exportSession.getLocalResolver().clear();
exportSession.getCaseResolver().clear();
exportSession.getCatchBlockResolver().clear();
exportSession.getLabelResolver().clear();
exportSession.getParameterResolver().clear();
}
}