+ //This kind of breaks away from tradition a little bit by doing the file checks here
+ // instead of in Semantic check, but doing it here is easier because we have a mapping early on
+ // if I wait until semantic check, I have to change ALL the type descriptors to match the new
+ // mapping and that's both ugly and tedious.
+ private void addMultiImport(String currentSource, String importPath, boolean isPackageDirectory) {
+ boolean found = false;
+ for (int j = 0; j < state.classpath.size(); j++) {
+ String path = (String) state.classpath.get(j);
+ File folder = new File(path, importPath.replace('.', '/'));
+ if (folder.exists()) {
+ found = true;
+ for (String file : folder.list()) {
+ // if the file is of type *.java add to multiImport list.
+ if (file.lastIndexOf('.') != -1 && file.substring(file.lastIndexOf('.')).equalsIgnoreCase(".java")) {
+ String classname = file.substring(0, file.length() - 5);
+ // single imports have precedence over multi-imports
+ if (!mandatoryImports.containsKey(classname)) {
+ //package files have precedence over multi-imports.
+ if (multiimports.containsKey(classname) && !isPackageDirectory) {
+ // put error in for later, in case we try to import
+ multiimports.put(classname, new Error("Error: class " + classname + " is defined more than once in a multi-import in " + currentSource));
+ } else {
+ multiimports.put(classname, importPath + "." + classname);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if(!found) {
+ throw new Error("Import package " + importPath + " in " + currentSource
+ + " cannot be resolved.");
+ }
+ }
+
+ public void parseInitializers(ClassDescriptor cn) {
+ Vector fv=cn.getFieldVec();
+ Iterator methodit = cn.getMethods();
+ HashMap<MethodDescriptor, Integer> md2pos = new HashMap<MethodDescriptor, Integer>();
+ while(methodit.hasNext()) {
+ MethodDescriptor currmd=(MethodDescriptor)methodit.next();
+ if(currmd.isConstructor()) {
+ BlockNode bn=state.getMethodBody(currmd);
+ // if there are super(...) invokation, the initializers should be invoked after that
+ int i = 0;
+ for(; i < bn.size(); i++) {
+ if(Kind.BlockExpressionNode==bn.get(i).kind()
+ &&(((BlockExpressionNode)bn.get(i)).getExpression() instanceof MethodInvokeNode)
+ &&((MethodInvokeNode)(((BlockExpressionNode)bn.get(i)).getExpression())).getMethodName().equals("super")) {
+ break;
+ }
+ }
+ if(i==bn.size()) {
+ md2pos.put(currmd, 0);
+ } else {
+ md2pos.put(currmd, i+1);
+ }
+ }
+ }
+ int pos = 0;
+ for(int i=0; i<fv.size(); i++) {
+ FieldDescriptor fd=(FieldDescriptor)fv.get(i);
+ if(fd.getExpressionNode()!=null) {
+ methodit = cn.getMethods();
+ while(methodit.hasNext()) {
+ MethodDescriptor currmd=(MethodDescriptor)methodit.next();
+ if(currmd.isConstructor()) {
+ int offset = md2pos.get(currmd);
+ BlockNode bn=state.getMethodBody(currmd);
+ NameNode nn=new NameNode(new NameDescriptor(fd.getSymbol()));
+ AssignmentNode an=new AssignmentNode(nn,fd.getExpressionNode(),new AssignOperation(1));
+ bn.addBlockStatementAt(new BlockExpressionNode(an), pos+offset);
+ }
+ }
+ pos++;
+ }
+ }
+ }
+
+ private ClassDescriptor parseEnumDecl(ClassDescriptor cn, ParseNode pn) {
+ String basename=pn.getChild("name").getTerminal();
+ String classname=(cn!=null)?cn.getClassName()+"$"+basename:basename;
+ ClassDescriptor ecd=new ClassDescriptor(cn!=null?cn.getPackage():null, classname, false);
+
+ if (cn!=null) {
+ if (packageName==null)
+ cn.getSingleImportMappings().put(basename,classname);
+ else
+ cn.getSingleImportMappings().put(basename,packageName+"."+classname);
+ }
+
+ pushChainMaps();
+ ecd.setImports(mandatoryImports, multiimports);