aspect JAModuleAccessControl { protected boolean Program.frontEndProcessingComplete = false; public void Program.setFrontEndProcessingComplete(boolean b) { this.frontEndProcessingComplete = b; } public boolean Program.isFrontEndProcessingComplete() { return this.frontEndProcessingComplete; } //may be too expensive inh lazy Program Modifiers.getHostProgram(); //module modifier syn lazy boolean Modifiers.isModule() = numModifier("module") != 0; syn boolean TypeDecl.isModule() = getModifiers().isModule(); syn boolean FieldDeclaration.isModule() = getModifiers().isModule(); syn boolean MethodDecl.isModule() = getModifiers().isModule(); syn boolean ConstructorDecl.isModule() = getModifiers().isModule(); eq Program.getChild().mayBeModule() = false; eq TypeDecl.getBodyDecl().mayBeModule() = false; inh boolean Modifiers.mayBeModule(); //may be module eq TypeDecl.getModifiers().mayBeModule() = true; eq FieldDeclaration.getModifiers().mayBeModule() = true; eq MethodDecl.getModifiers().mayBeModule() = true; eq ConstructorDecl.getModifiers().mayBeModule() = true; //error check refine Modifiers eq Modifiers.numProtectionModifiers() { return Modifiers.Modifiers.numProtectionModifiers() + numModifier("module"); } refine Modifiers public void Modifiers.checkModifiers() { Modifiers.Modifiers.checkModifiers(); if(numModifier("module") > 1) error("only one module allowed"); if (isModule() && !mayBeModule()) { error("modifier module not allowed in this context"); } if (isModule() && hostType().compilationUnit().getModuleCompilationUnit() == null) { warning("modifier module used in a a compilation unit that is not a module member. "); } } //modify accessibleFrom methods refine AccessControl eq TypeDecl.accessibleFromPackage(String packageName) = !isPrivate() && ( isPublic() || ( isModule() && compilationUnit().getModuleCompilationUnit() == compilationUnit().getHostProgram().getPackageToMCU(packageName) ) || hostPackage().equals(packageName) ); refine DeclareParentsAnalysis eq TypeDecl.accessibleFromExtend(TypeDecl type) { if (DeclareParentsAnalysis.TypeDecl.accessibleFromExtend(type)) { return true; } if (isModule()) { return this.compilationUnit().getModuleCompilationUnit() == type.compilationUnit().getModuleCompilationUnit(); } return false; } refine DeclareParentsAnalysis eq TypeDecl.accessibleFrom(TypeDecl type) { if (DeclareParentsAnalysis.TypeDecl.accessibleFrom(type)) { return true; } if (isModule()) { return this.compilationUnit().getModuleCompilationUnit() == type.compilationUnit().getModuleCompilationUnit(); } return false; } refine AccessControl eq MethodDecl.accessibleFrom(TypeDecl type) { if (AccessControl.MethodDecl.accessibleFrom(type)) { return true; } if (isModule()) { return this.hostType().compilationUnit().getModuleCompilationUnit() == type.compilationUnit().getModuleCompilationUnit(); } return false; } refine DeclareParentsAnalysis eq ConstructorDecl.accessibleFrom(TypeDecl type) { if (DeclareParentsAnalysis.ConstructorDecl.accessibleFrom(type)) { return true; } if (isModule()) { return this.hostType().compilationUnit().getModuleCompilationUnit() == type.compilationUnit().getModuleCompilationUnit(); } return false; } refine AccessControl eq FieldDeclaration.accessibleFrom(TypeDecl type) { if (AccessControl.FieldDeclaration.accessibleFrom(type)) { return true; } if (isModule()) { return this.hostType().compilationUnit().getModuleCompilationUnit() == type.compilationUnit().getModuleCompilationUnit(); } return false; } }