| /* |
| * 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.JClass; |
| import com.android.jack.ir.ast.JClassOrInterface; |
| import com.android.jack.ir.ast.JDefinedClass; |
| import com.android.jack.ir.ast.JDefinedClassOrInterface; |
| import com.android.jack.ir.ast.JField; |
| import com.android.jack.ir.ast.JMethod; |
| import com.android.jack.ir.ast.JPackage; |
| import com.android.jack.jayce.JayceClassOrInterfaceLoader; |
| import com.android.jack.jayce.NodeLevel; |
| 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 com.android.jack.lookup.JMethodLookupException; |
| import com.android.jack.util.NamingTools; |
| |
| import java.io.IOException; |
| import java.util.Collections; |
| import java.util.List; |
| |
| import javax.annotation.CheckForNull; |
| import javax.annotation.Nonnull; |
| |
| /** |
| * Java class type reference expression. |
| */ |
| public class NClassType extends NDeclaredType { |
| |
| @Nonnull |
| public static final Token TOKEN = Token.CLASS; |
| |
| public int modifiers; |
| |
| @CheckForNull |
| public String signature; |
| |
| @CheckForNull |
| public String superClass; |
| |
| @CheckForNull |
| public String enclosingType; |
| |
| @CheckForNull |
| public String enclosingMethodClass; |
| |
| @CheckForNull |
| public String enclosingMethod; |
| |
| @Nonnull |
| public List<String> inners = Collections.emptyList(); |
| |
| @Nonnull |
| public List<String> superInterfaces = Collections.emptyList(); |
| |
| @Nonnull |
| public List<NField> fields = Collections.emptyList(); |
| |
| @Nonnull |
| public List<NAnnotationLiteral> annotations = Collections.emptyList(); |
| |
| @Nonnull |
| public List<NMarker> markers = Collections.emptyList(); |
| |
| @CheckForNull |
| public NSourceInfo sourceInfo; |
| |
| @Override |
| public void importFromJast(@Nonnull ImportHelper loader, @Nonnull Object node) { |
| JDefinedClass jClassType = (JDefinedClass) node; |
| modifiers = jClassType.getModifier(); |
| signature = ImportHelper.getSignatureName(jClassType); |
| superClass = ImportHelper.getSignatureName(jClassType.getSuperClass()); |
| superInterfaces = ImportHelper.getSignatureNameList(jClassType.getImplements()); |
| enclosingType = ImportHelper.getSignatureName(jClassType.getEnclosingType()); |
| enclosingMethodClass = ImportHelper.getMethodClassSignature(jClassType.getEnclosingMethod()); |
| enclosingMethod = ImportHelper.getMethodSignature(jClassType.getEnclosingMethod()); |
| inners = ImportHelper.getSignatureNameList(jClassType.getMemberTypes()); |
| fields = loader.load(NField.class, jClassType.getFields()); |
| methods = loader.load(NMethod.class, jClassType.getMethods()); |
| annotations = loader.load(NAnnotationLiteral.class, jClassType.getAnnotations()); |
| markers = loader.load(NMarker.class, jClassType.getAllMarkers()); |
| sourceInfo = loader.load(jClassType.getSourceInfo()); |
| } |
| |
| @Nonnull |
| @Override |
| public JDefinedClass exportAsJast(@Nonnull ExportSession exportSession) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| @Nonnull |
| public JDefinedClass create(@Nonnull JPackage enclosingPackage, |
| @Nonnull JayceClassOrInterfaceLoader loader) { |
| assert signature != null; |
| assert sourceInfo != null; |
| String binaryName = NamingTools.getClassBinaryNameFromDescriptor(signature); |
| String simpleName = NamingTools.getSimpleClassNameFromBinaryName(binaryName); |
| SourceInfo jSourceInfo = sourceInfo.exportAsJast( |
| new ExportSession(loader.getLookup(), enclosingPackage.getSession(), NodeLevel.TYPES)); |
| JDefinedClass jClassType = |
| new JDefinedClass(jSourceInfo, simpleName, modifiers, enclosingPackage, loader); |
| return jClassType; |
| } |
| |
| @Override |
| public void updateToStructure(@Nonnull JDefinedClassOrInterface loading, |
| @Nonnull JayceClassOrInterfaceLoader loader) { |
| assert sourceInfo != null; |
| assert signature != null; |
| JDefinedClass jClassType = (JDefinedClass) loading; |
| ExportSession exportSession = new ExportSession(loader.getLookup(), loading.getSession(), |
| NodeLevel.STRUCTURE); |
| exportSession.setCurrentType(jClassType); |
| if (superClass != null) { |
| jClassType.setSuperClass(exportSession.getLookup().getClass(superClass)); |
| } |
| for (String superInterface : superInterfaces) { |
| jClassType.addImplements(exportSession.getLookup().getInterface(superInterface)); |
| } |
| if (enclosingType != null) { |
| jClassType.setEnclosingType( |
| (JClassOrInterface) exportSession.getLookup().getType(enclosingType)); |
| } |
| if (enclosingMethodClass != null) { |
| assert enclosingMethod != null; |
| JClass enclosingMethodJClass = |
| exportSession.getLookup().getClass(enclosingMethodClass); |
| if (enclosingMethodJClass instanceof JDefinedClass) { |
| try { |
| jClassType.setEnclosingMethod( |
| exportSession.getDeclaredMethod((JDefinedClass) enclosingMethodJClass, |
| enclosingMethod)); |
| } catch (JMethodLookupException e) { |
| // Method does not longer exists but anonymous already exists, could be trigger by build |
| // tricky mechanism, skip it to go ahead |
| } |
| } |
| } |
| for (String memberType : inners) { |
| jClassType.addMemberType( |
| (JClassOrInterface) exportSession.getLookup().getType(memberType)); |
| } |
| for (NField field : fields) { |
| JField jField = field.exportAsJast(exportSession); |
| jField.setEnclosingType(jClassType); |
| jClassType.addField(jField); |
| } |
| for (NMethod method : methods) { |
| JMethod jMethod = method.exportAsJast(exportSession, loader); |
| jMethod.setEnclosingType(jClassType); |
| jClassType.addMethod(jMethod); |
| } |
| for (NAnnotationLiteral annotation : annotations) { |
| jClassType.addAnnotation(annotation.exportAsJast(exportSession)); |
| } |
| for (NMarker marker : markers) { |
| jClassType.addMarker(marker.exportAsJast(exportSession)); |
| } |
| } |
| |
| @Override |
| public void writeContent(@Nonnull JayceInternalWriterImpl out) throws IOException { |
| out.writeInt(modifiers); |
| out.writeId(signature); |
| out.writeId(superClass); |
| out.writeIds(superInterfaces); |
| out.writeId(enclosingType); |
| out.writeId(enclosingMethodClass); |
| out.writeId(enclosingMethod); |
| out.writeIds(inners); |
| out.writeNodes(fields); |
| out.writeNodes(methods); |
| out.writeNodes(annotations); |
| out.writeNodes(markers); |
| |
| } |
| |
| @Override |
| public void readContent(@Nonnull JayceInternalReaderImpl in) throws IOException { |
| level = in.getNodeLevel(); |
| modifiers = in.readInt(); |
| signature = in.readId(); |
| superClass = in.readId(); |
| superInterfaces = in.readIds(); |
| enclosingType = in.readId(); |
| enclosingMethodClass = in.readId(); |
| enclosingMethod = in.readId(); |
| inners = in.readIds(); |
| fields = in.readNodes(NField.class); |
| methods = in.readNodes(NMethod.class); |
| annotations = in.readNodes(NAnnotationLiteral.class); |
| markers = in.readNodes(NMarker.class); |
| } |
| |
| @Nonnull |
| @Override |
| public Token getToken() { |
| return TOKEN; |
| } |
| |
| @Nonnull |
| @Override |
| public String getSignature() { |
| assert signature != null; |
| return signature; |
| } |
| |
| @Override |
| @Nonnull |
| public NSourceInfo getSourceInfos() { |
| assert sourceInfo != null; |
| return sourceInfo; |
| } |
| |
| @Override |
| public void setSourceInfos(@Nonnull NSourceInfo sourceInfo) { |
| this.sourceInfo = sourceInfo; |
| } |
| |
| } |