diff --git a/build.xml b/build.xml
index 6c91c946fa5..c799c56523e 100644
--- a/build.xml
+++ b/build.xml
@@ -9,6 +9,11 @@
+
+
+
+
+
@@ -26,9 +31,21 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -49,7 +66,11 @@
-
+
+
+
+
+
diff --git a/compiler/backend/src/org/jetbrains/jet/compiler/CompileEnvironment.java b/compiler/backend/src/org/jetbrains/jet/compiler/CompileEnvironment.java
index d2ba73c02ef..669bda88f70 100644
--- a/compiler/backend/src/org/jetbrains/jet/compiler/CompileEnvironment.java
+++ b/compiler/backend/src/org/jetbrains/jet/compiler/CompileEnvironment.java
@@ -5,7 +5,9 @@ import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiFile;
import com.intellij.util.Function;
import com.intellij.util.Processor;
import jet.modules.IModuleBuilder;
@@ -22,6 +24,8 @@ import java.io.*;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import java.util.jar.*;
@@ -53,14 +57,18 @@ public class CompileEnvironment {
}
public boolean initializeKotlinRuntime() {
+ return initializeKotlinRuntime(myEnvironment);
+ }
+
+ public static boolean initializeKotlinRuntime(JetCoreEnvironment environment) {
final File unpackedRuntimePath = getUnpackedRuntimePath();
if (unpackedRuntimePath != null) {
- myEnvironment.addToClasspath(unpackedRuntimePath);
+ environment.addToClasspath(unpackedRuntimePath);
}
else {
final File runtimeJarPath = getRuntimeJarPath();
if (runtimeJarPath != null && runtimeJarPath.exists()) {
- myEnvironment.addToClasspath(runtimeJarPath);
+ environment.addToClasspath(runtimeJarPath);
}
else {
return false;
@@ -147,7 +155,7 @@ public class CompileEnvironment {
return null;
}
- public void compileModuleScript(String moduleFile) {
+ public void compileModuleScript(String moduleFile, String jarPath, boolean jarRuntime) {
final IModuleSetBuilder moduleSetBuilder = loadModuleScript(moduleFile);
if (moduleSetBuilder == null) {
return;
@@ -156,9 +164,9 @@ public class CompileEnvironment {
final String directory = new File(moduleFile).getParent();
for (IModuleBuilder moduleBuilder : moduleSetBuilder.getModules()) {
ClassFileFactory moduleFactory = compileModule(moduleBuilder, directory);
- final String path = new File(directory, moduleBuilder.getModuleName() + ".jar").getPath();
+ final String path = jarPath != null ? jarPath : new File(directory, moduleBuilder.getModuleName() + ".jar").getPath();
try {
- writeToJar(moduleFactory, new FileOutputStream(path), null, true);
+ writeToJar(moduleFactory, new FileOutputStream(path), null, jarRuntime);
} catch (FileNotFoundException e) {
throw new CompileEnvironmentException("Invalid jar path " + path, e);
}
@@ -168,25 +176,7 @@ public class CompileEnvironment {
public IModuleSetBuilder loadModuleScript(String moduleFile) {
CompileSession scriptCompileSession = new CompileSession(myEnvironment);
scriptCompileSession.addSources(moduleFile);
-
- URL url = CompileEnvironment.class.getClassLoader().getResource("ModuleBuilder.kt");
- if (url != null) {
- String path = url.getPath();
- if (path.startsWith("file:")) {
- path = path.substring(5);
- }
- final VirtualFile vFile = myEnvironment.getJarFileSystem().findFileByPath(path);
- if (vFile == null) {
- throw new CompileEnvironmentException("Couldn't load ModuleBuilder.kt from runtime jar: "+ url);
- }
- scriptCompileSession.addSources(vFile);
- }
- else {
- // building from source
- final String homeDirectory = getHomeDirectory();
- final File file = new File(homeDirectory, "stdlib/ktSrc/ModuleBuilder.kt");
- scriptCompileSession.addSources(myEnvironment.getLocalFileSystem().findFileByPath(file.getPath()));
- }
+ scriptCompileSession.addStdLibSources();
if (!scriptCompileSession.analyze(myErrorStream)) {
return null;
@@ -223,6 +213,7 @@ public class CompileEnvironment {
public ClassFileFactory compileModule(IModuleBuilder moduleBuilder, String directory) {
CompileSession moduleCompileSession = new CompileSession(myEnvironment);
+ moduleCompileSession.addStdLibSources();
for (String sourceFile : moduleBuilder.getSourceFiles()) {
moduleCompileSession.addSources(new File(directory, sourceFile).getPath());
}
@@ -239,6 +230,17 @@ public class CompileEnvironment {
return new File(PathManager.getResourceRoot(CompileEnvironment.class, "/org/jetbrains/jet/compiler/CompileEnvironment.class")).getParentFile().getParentFile().getParent();
}
+ private static final List sanitized = Arrays.asList("kotlin/", "std/");
+ public static boolean skipFile(String name) {
+ boolean skip = false;
+ for (String prefix : sanitized) {
+ if(name.startsWith(prefix)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
public static void writeToJar(ClassFileFactory factory, final OutputStream fos, @Nullable String mainClass, boolean includeRuntime) {
try {
Manifest manifest = new Manifest();
@@ -251,8 +253,10 @@ public class CompileEnvironment {
JarOutputStream stream = new JarOutputStream(fos, manifest);
try {
for (String file : factory.files()) {
- stream.putNextEntry(new JarEntry(file));
- stream.write(factory.asBytes(file));
+ if(!skipFile(file)) {
+ stream.putNextEntry(new JarEntry(file));
+ stream.write(factory.asBytes(file));
+ }
}
if (includeRuntime) {
writeRuntimeToJar(stream);
@@ -316,9 +320,10 @@ public class CompileEnvironment {
}
}
- public void compileBunchOfSources(String sourceFileOrDir, String jar, String outputDir) {
+ public void compileBunchOfSources(String sourceFileOrDir, String jar, String outputDir, boolean includeRuntime) {
CompileSession session = new CompileSession(myEnvironment);
session.addSources(sourceFileOrDir);
+ session.addStdLibSources();
String mainClass = null;
for (JetNamespace namespace : session.getSourceFileNamespaces()) {
@@ -334,7 +339,7 @@ public class CompileEnvironment {
ClassFileFactory factory = session.generate();
if (jar != null) {
try {
- writeToJar(factory, new FileOutputStream(jar), mainClass, true);
+ writeToJar(factory, new FileOutputStream(jar), mainClass, includeRuntime);
} catch (FileNotFoundException e) {
throw new CompileEnvironmentException("Invalid jar path " + jar, e);
}
@@ -350,13 +355,14 @@ public class CompileEnvironment {
private static void writeToOutputDirectory(ClassFileFactory factory, final String outputDir) {
List files = factory.files();
for (String file : files) {
- File target = new File(outputDir, file);
- try {
- FileUtil.writeToFile(target, factory.asBytes(file));
- } catch (IOException e) {
- throw new CompileEnvironmentException(e);
+ if(!skipFile(file)) {
+ File target = new File(outputDir, file);
+ try {
+ FileUtil.writeToFile(target, factory.asBytes(file));
+ } catch (IOException e) {
+ throw new CompileEnvironmentException(e);
+ }
}
}
}
-
}
diff --git a/compiler/backend/src/org/jetbrains/jet/compiler/CompileSession.java b/compiler/backend/src/org/jetbrains/jet/compiler/CompileSession.java
index e90fda9eb8a..91a0dccaf9e 100644
--- a/compiler/backend/src/org/jetbrains/jet/compiler/CompileSession.java
+++ b/compiler/backend/src/org/jetbrains/jet/compiler/CompileSession.java
@@ -16,6 +16,7 @@ import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.java.JavaDefaultImports;
import org.jetbrains.jet.plugin.JetFileType;
+import java.io.File;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;
@@ -47,7 +48,22 @@ public class CompileSession {
return;
}
- addSources(vFile);
+ addSources(new File(path));
+ }
+
+ private void addSources(File file) {
+ if(file.isDirectory()) {
+ for (File child : file.listFiles()) {
+ addSources(child);
+ }
+ }
+ else {
+ VirtualFile fileByPath = myEnvironment.getLocalFileSystem().findFileByPath(file.getAbsolutePath());
+ PsiFile psiFile = PsiManager.getInstance(myEnvironment.getProject()).findFile(fileByPath);
+ if(psiFile instanceof JetFile) {
+ mySourceFileNamespaces.add(((JetFile) psiFile).getRootNamespace());
+ }
+ }
}
public void addSources(VirtualFile vFile) {
@@ -66,13 +82,6 @@ public class CompileSession {
}
}
- public void addLibrarySources(VirtualFile vFile) {
- PsiFile psiFile = PsiManager.getInstance(myEnvironment.getProject()).findFile(vFile);
- if (psiFile instanceof JetFile) {
- myLibrarySourceFileNamespaces.add(((JetFile) psiFile).getRootNamespace());
- }
- }
-
public List getSourceFileNamespaces() {
return mySourceFileNamespaces;
}
@@ -104,4 +113,22 @@ public class CompileSession {
generationState.compileCorrectNamespaces(myBindingContext, mySourceFileNamespaces);
return generationState.createText();
}
+
+ public boolean addStdLibSources() {
+ final File unpackedRuntimePath = CompileEnvironment.getUnpackedRuntimePath();
+ if (unpackedRuntimePath != null) {
+ addSources(new File(unpackedRuntimePath, "../../../stdlib/ktSrc").getAbsoluteFile());
+ }
+ else {
+ final File runtimeJarPath = CompileEnvironment.getRuntimeJarPath();
+ if (runtimeJarPath != null && runtimeJarPath.exists()) {
+ // todo
+ throw new UnsupportedOperationException("Loading of stdlib sources from jar");
+ }
+ else {
+ return false;
+ }
+ }
+ return true;
+ }
}
diff --git a/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java b/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java
index 00b8cb1e85b..56db85a522d 100644
--- a/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java
+++ b/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java
@@ -23,6 +23,8 @@ public class KotlinCompiler {
public String src;
@Argument(value = "module", description = "module to compile")
public String module;
+ @Argument(value = "includeRuntime", description = "include Kotlin runtime in to resulting jar")
+ public boolean includeRuntime;
}
public static void main(String[] args) {
@@ -32,7 +34,7 @@ public class KotlinCompiler {
Args.parse(arguments, args);
}
catch (Throwable t) {
- System.out.println("Usage: KotlinCompiler [-output |-jar ] -src ");
+ System.out.println("Usage: KotlinCompiler [-output |-jar ] [-src |-module ] [-includeRuntime]");
t.printStackTrace();
return;
}
@@ -47,11 +49,11 @@ public class KotlinCompiler {
}
if (arguments.module != null) {
- environment.compileModuleScript(arguments.module);
+ environment.compileModuleScript(arguments.module, arguments.jar, arguments.includeRuntime);
return;
}
else {
- environment.compileBunchOfSources(arguments.src, arguments.jar, arguments.outputDir);
+ environment.compileBunchOfSources(arguments.src, arguments.jar, arguments.outputDir, arguments.includeRuntime);
}
} catch (CompileEnvironmentException e) {
System.out.println(e.getMessage());
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java
index 2ea2a103180..fc8ce9013f2 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java
@@ -44,7 +44,10 @@ public interface Errors {
}
};
UnresolvedReferenceDiagnosticFactory UNRESOLVED_REFERENCE = new UnresolvedReferenceDiagnosticFactory("Unresolved reference");
- RedeclarationDiagnosticFactory REDECLARATION = RedeclarationDiagnosticFactory.INSTANCE;
+
+ RedeclarationDiagnosticFactory REDECLARATION = RedeclarationDiagnosticFactory.REDECLARATION;
+ RedeclarationDiagnosticFactory NAME_SHADOWING = RedeclarationDiagnosticFactory.NAME_SHADOWING;
+
PsiElementOnlyDiagnosticFactory2 TYPE_MISMATCH = PsiElementOnlyDiagnosticFactory2.create(ERROR, "Type mismatch: inferred type is {1} but {0} was expected");
ParameterizedDiagnosticFactory1> INCOMPATIBLE_MODIFIERS = new ParameterizedDiagnosticFactory1>(ERROR, "Incompatible modifiers: ''{0}''") {
@Override
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/RedeclarationDiagnostic.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/RedeclarationDiagnostic.java
index 3a8c2f02733..648c8bfe5d2 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/RedeclarationDiagnostic.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/RedeclarationDiagnostic.java
@@ -15,8 +15,8 @@ import static org.jetbrains.jet.lang.diagnostics.Severity.ERROR;
public interface RedeclarationDiagnostic extends DiagnosticWithPsiElement {
public class SimpleRedeclarationDiagnostic extends DiagnosticWithPsiElementImpl implements RedeclarationDiagnostic {
- public SimpleRedeclarationDiagnostic(@NotNull PsiElement psiElement, @NotNull String name) {
- super(RedeclarationDiagnosticFactory.INSTANCE, ERROR, "Redeclaration: " + name, psiElement);
+ public SimpleRedeclarationDiagnostic(@NotNull PsiElement psiElement, @NotNull String name, RedeclarationDiagnosticFactory factory) {
+ super(factory, factory.severity, factory.makeMessage(name), psiElement);
}
}
@@ -24,11 +24,13 @@ public interface RedeclarationDiagnostic extends DiagnosticWithPsiElement operations = new HashSet();
Precedence[] values = Precedence.values();
@@ -272,7 +275,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
precedence.parseHigherPrecedence(this);
- while (!myBuilder.newlineBeforeCurrentToken() && atSet(precedence.getOperations())) {
+ while (!interruptedWithNewLine() && atSet(precedence.getOperations())) {
IElementType operation = tt();
parseOperationReference();
@@ -328,7 +331,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
PsiBuilder.Marker expression = mark();
parseAtomicExpression();
while (true) {
- if (myBuilder.newlineBeforeCurrentToken()) {
+ if (interruptedWithNewLine()) {
break;
}
else if (at(LBRACKET)) {
@@ -1704,4 +1707,8 @@ public class JetExpressionParsing extends AbstractJetParsing {
protected JetParsing create(SemanticWhitespaceAwarePsiBuilder builder) {
return myJetParsing.create(builder);
}
+
+ private boolean interruptedWithNewLine() {
+ return !ALLOW_NEWLINE_OPERATIONS.contains(tt()) && myBuilder.newlineBeforeCurrentToken();
+ }
}
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetParsing.java b/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetParsing.java
index 9a97153ce8d..814752f7eaa 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetParsing.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetParsing.java
@@ -124,9 +124,11 @@ public class JetParsing extends AbstractJetParsing {
parseNamespaceName();
if (at(LBRACE)) {
+ // Because it's blocked namespace and it will be parsed as one of top level objects
firstEntry.rollbackTo();
return;
}
+
firstEntry.drop();
consumeIf(SEMICOLON);
@@ -134,6 +136,7 @@ public class JetParsing extends AbstractJetParsing {
firstEntry.rollbackTo();
}
+ // TODO: Duplicate with parsing imports in parseToplevelDeclarations
while (at(IMPORT_KEYWORD)) {
parseImportDirective();
}
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/parsing/SemanticWhitespaceAwarePsiBuilderImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/parsing/SemanticWhitespaceAwarePsiBuilderImpl.java
index e211deb85f4..68ecfaafd88 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/parsing/SemanticWhitespaceAwarePsiBuilderImpl.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/parsing/SemanticWhitespaceAwarePsiBuilderImpl.java
@@ -26,26 +26,36 @@ public class SemanticWhitespaceAwarePsiBuilderImpl extends PsiBuilderAdapter imp
@Override
public boolean newlineBeforeCurrentToken() {
if (!newlinesEnabled.peek()) return false;
+
if (eof()) return true;
+
// TODO: maybe, memoize this somehow?
for (int i = 1; i <= getCurrentOffset(); i++) {
IElementType previousToken = rawLookup(-i);
+
if (previousToken == JetTokens.BLOCK_COMMENT
|| previousToken == JetTokens.DOC_COMMENT
|| previousToken == JetTokens.EOL_COMMENT) {
continue;
}
+
if (previousToken != TokenType.WHITE_SPACE) {
break;
}
+
int previousTokenStart = rawTokenTypeStart(-i);
int previousTokenEnd = rawTokenTypeStart(-i + 1);
+
assert previousTokenStart >= 0;
assert previousTokenEnd < getOriginalText().length();
+
for (int j = previousTokenStart; j < previousTokenEnd; j++) {
- if (getOriginalText().charAt(j) == '\n') return true;
+ if (getOriginalText().charAt(j) == '\n') {
+ return true;
+ }
}
}
+
return false;
}
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java
index ba492a83cde..c66af6e8f03 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java
@@ -123,4 +123,35 @@ public class DescriptorUtils {
}
return NO_RECEIVER;
}
+
+ /**
+ * The primary case for local extensions is the following:
+ *
+ * I had a locally declared extension function or a local variable of function type called foo
+ * And I called it on my x
+ * Now, someone added function foo() to the class of x
+ * My code should not change
+ *
+ * thus
+ *
+ * local extension prevail over members (and members prevail over all non-local extensions)
+ */
+ public static boolean isLocal(DeclarationDescriptor containerOfTheCurrentLocality, DeclarationDescriptor candidate) {
+ if (candidate instanceof ValueParameterDescriptor) {
+ return true;
+ }
+ DeclarationDescriptor parent = candidate.getContainingDeclaration();
+ if (!(parent instanceof FunctionDescriptor)) {
+ return false;
+ }
+ FunctionDescriptor functionDescriptor = (FunctionDescriptor) parent;
+ DeclarationDescriptor current = containerOfTheCurrentLocality;
+ while (current != null) {
+ if (current == functionDescriptor) {
+ return true;
+ }
+ current = current.getContainingDeclaration();
+ }
+ return false;
+ }
}
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/TaskPrioritizer.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/TaskPrioritizer.java
index 872781fb28b..823666d4ed2 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/TaskPrioritizer.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/TaskPrioritizer.java
@@ -5,12 +5,11 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
-import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
-import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.psi.Call;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.psi.JetSuperExpression;
import org.jetbrains.jet.lang.resolve.BindingContext;
+import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.calls.autocasts.AutoCastService;
import org.jetbrains.jet.lang.resolve.calls.autocasts.AutoCastServiceImpl;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
@@ -36,7 +35,7 @@ import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor
Collection> allDescriptors, DeclarationDescriptor containerOfTheCurrentLocality, Collection> local, Collection> nonlocal) {
for (ResolvedCallImpl resolvedCall : allDescriptors) {
- if (isLocal(containerOfTheCurrentLocality, resolvedCall.getCandidateDescriptor())) {
+ if (DescriptorUtils.isLocal(containerOfTheCurrentLocality, resolvedCall.getCandidateDescriptor())) {
local.add(resolvedCall);
}
else {
@@ -45,37 +44,6 @@ import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor
}
}
- /**
- * The primary case for local extensions is the following:
- *
- * I had a locally declared extension function or a local variable of function type called foo
- * And I called it on my x
- * Now, someone added function foo() to the class of x
- * My code should not change
- *
- * thus
- *
- * local extension prevail over members (and members prevail over all non-local extensions)
- */
- private static boolean isLocal(DeclarationDescriptor containerOfTheCurrentLocality, DeclarationDescriptor candidate) {
- if (candidate instanceof ValueParameterDescriptor) {
- return true;
- }
- DeclarationDescriptor parent = candidate.getContainingDeclaration();
- if (!(parent instanceof FunctionDescriptor)) {
- return false;
- }
- FunctionDescriptor functionDescriptor = (FunctionDescriptor) parent;
- DeclarationDescriptor current = containerOfTheCurrentLocality;
- while (current != null) {
- if (current == functionDescriptor) {
- return true;
- }
- current = current.getContainingDeclaration();
- }
- return false;
- }
-
@Nullable
/*package*/ static JetSuperExpression getReceiverSuper(@NotNull ReceiverDescriptor receiver) {
if (receiver instanceof ExpressionReceiver) {
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingVisitor.java
index 381d52bdf91..f573e39e79a 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingVisitor.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingVisitor.java
@@ -6,10 +6,14 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
+import org.jetbrains.jet.lang.diagnostics.Errors;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults;
+import org.jetbrains.jet.lang.resolve.DescriptorUtils;
+import org.jetbrains.jet.lang.resolve.calls.TaskPrioritizers;
+import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
@@ -209,6 +213,16 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
}
variableDescriptor = context.getDescriptorResolver().resolveLocalVariableDescriptor(context.scope.getContainingDeclaration(), loopParameter, expectedParameterType);
}
+
+ {
+ // http://youtrack.jetbrains.net/issue/KT-527
+
+ VariableDescriptor olderVariable = context.scope.getVariable(variableDescriptor.getName());
+ if (olderVariable != null && DescriptorUtils.isLocal(context.scope.getContainingDeclaration(), olderVariable)) {
+ context.trace.report(Errors.NAME_SHADOWING.on(variableDescriptor, context.trace.getBindingContext()));
+ }
+ }
+
loopScope.addVariableDescriptor(variableDescriptor);
}
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorForStatements.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorForStatements.java
index 8c2c8a5da04..59642c4c73e 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorForStatements.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorForStatements.java
@@ -7,6 +7,7 @@ import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.diagnostics.Errors;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
+import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace;
import org.jetbrains.jet.lang.resolve.TopDownAnalyzer;
import org.jetbrains.jet.lang.resolve.calls.CallMaker;
@@ -91,6 +92,13 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
JetType outType = propertyDescriptor.getOutType();
JetType initializerType = facade.getType(initializer, context.replaceExpectedType(outType).replaceScope(scope));
}
+
+ {
+ VariableDescriptor olderVariable = scope.getVariable(propertyDescriptor.getName());
+ if (olderVariable != null && DescriptorUtils.isLocal(propertyDescriptor.getContainingDeclaration(), olderVariable)) {
+ context.trace.report(Errors.NAME_SHADOWING.on(propertyDescriptor, context.trace.getBindingContext()));
+ }
+ }
scope.addVariableDescriptor(propertyDescriptor);
return checkExpectedType(property, context);
diff --git a/compiler/testData/checkerWithErrorTypes/quick/control/ForWithoutBraces.jet b/compiler/testData/checkerWithErrorTypes/quick/control/ForWithoutBraces.jet
new file mode 100644
index 00000000000..d79dd7e77e0
--- /dev/null
+++ b/compiler/testData/checkerWithErrorTypes/quick/control/ForWithoutBraces.jet
@@ -0,0 +1,8 @@
+// http://youtrack.jetbrains.net/issue/KT-552
+// KT-552 For variable unresolved if loop body is not block
+
+fun ff() {
+ var i = 1
+ for (j in 1..10)
+ i += j
+}
diff --git a/compiler/testData/checkerWithErrorTypes/quick/regressions/kt337.jet b/compiler/testData/checkerWithErrorTypes/quick/regressions/kt337.jet
new file mode 100644
index 00000000000..7cac265e866
--- /dev/null
+++ b/compiler/testData/checkerWithErrorTypes/quick/regressions/kt337.jet
@@ -0,0 +1,14 @@
+//KT-337 Can't break a line before a dot
+
+class A() {
+ fun foo() {}
+}
+
+fun test() {
+ val a = A()
+
+ a
+
+ .foo() // Should be a valid expression
+
+}
diff --git a/compiler/testData/checkerWithErrorTypes/quick/shadowing/ShadowParameterInFunctionBody.jet b/compiler/testData/checkerWithErrorTypes/quick/shadowing/ShadowParameterInFunctionBody.jet
new file mode 100644
index 00000000000..3f99c1e45bb
--- /dev/null
+++ b/compiler/testData/checkerWithErrorTypes/quick/shadowing/ShadowParameterInFunctionBody.jet
@@ -0,0 +1,5 @@
+
+fun f(p: Int): Int {
+ val p = 2
+ return p
+}
diff --git a/compiler/testData/checkerWithErrorTypes/quick/shadowing/ShadowParameterInNestedBlockInFor.jet b/compiler/testData/checkerWithErrorTypes/quick/shadowing/ShadowParameterInNestedBlockInFor.jet
new file mode 100644
index 00000000000..e3e91fbe857
--- /dev/null
+++ b/compiler/testData/checkerWithErrorTypes/quick/shadowing/ShadowParameterInNestedBlockInFor.jet
@@ -0,0 +1,7 @@
+fun f(i: Int) {
+ for (j in 1..100) {
+ {
+ var i = 12
+ }
+ }
+}
diff --git a/compiler/testData/checkerWithErrorTypes/quick/shadowing/ShadowPropertyInClosure.jet b/compiler/testData/checkerWithErrorTypes/quick/shadowing/ShadowPropertyInClosure.jet
new file mode 100644
index 00000000000..c785e3f5fc7
--- /dev/null
+++ b/compiler/testData/checkerWithErrorTypes/quick/shadowing/ShadowPropertyInClosure.jet
@@ -0,0 +1,3 @@
+val i = 17
+
+val f = { (): Int => var i = 17; i }
diff --git a/compiler/testData/checkerWithErrorTypes/quick/shadowing/ShadowPropertyInFor.jet b/compiler/testData/checkerWithErrorTypes/quick/shadowing/ShadowPropertyInFor.jet
new file mode 100644
index 00000000000..e0d4766e89f
--- /dev/null
+++ b/compiler/testData/checkerWithErrorTypes/quick/shadowing/ShadowPropertyInFor.jet
@@ -0,0 +1,11 @@
+class RedefinePropertyInFor() {
+
+ var i = 1
+
+ fun ff() {
+ for (i in 0..10) {
+ }
+ }
+
+}
+
diff --git a/compiler/testData/checkerWithErrorTypes/quick/shadowing/ShadowPropertyInFunction.jet b/compiler/testData/checkerWithErrorTypes/quick/shadowing/ShadowPropertyInFunction.jet
new file mode 100644
index 00000000000..cacf415e65e
--- /dev/null
+++ b/compiler/testData/checkerWithErrorTypes/quick/shadowing/ShadowPropertyInFunction.jet
@@ -0,0 +1,10 @@
+class RedefinePropertyInFunction() {
+
+ var i = 17
+
+ fun f(): Int {
+ var i = 18
+ return i
+ }
+
+}
diff --git a/compiler/testData/checkerWithErrorTypes/quick/shadowing/ShadowVariableInFor.jet b/compiler/testData/checkerWithErrorTypes/quick/shadowing/ShadowVariableInFor.jet
new file mode 100644
index 00000000000..b62b6d0ea30
--- /dev/null
+++ b/compiler/testData/checkerWithErrorTypes/quick/shadowing/ShadowVariableInFor.jet
@@ -0,0 +1,6 @@
+fun ff(): Int {
+ var i = 1
+ for (i in 0..10) {
+ }
+ return i
+}
diff --git a/compiler/testData/checkerWithErrorTypes/quick/shadowing/ShadowVariableInNestedBlock.jet b/compiler/testData/checkerWithErrorTypes/quick/shadowing/ShadowVariableInNestedBlock.jet
new file mode 100644
index 00000000000..2fd755bdc1c
--- /dev/null
+++ b/compiler/testData/checkerWithErrorTypes/quick/shadowing/ShadowVariableInNestedBlock.jet
@@ -0,0 +1,7 @@
+fun ff(): Int {
+ var i = 1
+ {
+ val i = 2
+ }
+ return i
+}
diff --git a/compiler/testData/checkerWithErrorTypes/quick/shadowing/ShadowVariableInNestedClosure.jet b/compiler/testData/checkerWithErrorTypes/quick/shadowing/ShadowVariableInNestedClosure.jet
new file mode 100644
index 00000000000..d9dd9110893
--- /dev/null
+++ b/compiler/testData/checkerWithErrorTypes/quick/shadowing/ShadowVariableInNestedClosure.jet
@@ -0,0 +1,5 @@
+fun f(): Int {
+ var i = 17
+ { (): Unit => var i = 18 }
+ return i
+}
diff --git a/compiler/testData/checkerWithErrorTypes/quick/shadowing/ShadowVariableInNestedClosureParam.jet b/compiler/testData/checkerWithErrorTypes/quick/shadowing/ShadowVariableInNestedClosureParam.jet
new file mode 100644
index 00000000000..6ba5fd4c919
--- /dev/null
+++ b/compiler/testData/checkerWithErrorTypes/quick/shadowing/ShadowVariableInNestedClosureParam.jet
@@ -0,0 +1,5 @@
+fun ff(): Int {
+ var i = 1
+ { (i: Int) => i }
+ return i
+}
diff --git a/compiler/testData/codegen/regressions/kt640.jet b/compiler/testData/codegen/regressions/kt640.jet
new file mode 100644
index 00000000000..705fc1f338c
--- /dev/null
+++ b/compiler/testData/codegen/regressions/kt640.jet
@@ -0,0 +1,29 @@
+namespace demo
+
+public open class Identifier(myName : T?, myHasDollar : Boolean) {
+ {
+ $myName = myName
+ $myHasDollar = myHasDollar
+ }
+
+ private val myName : T?
+ private var myHasDollar : Boolean
+ private var myNullable : Boolean = true
+
+ open public fun getName() : T? {
+ return myName
+ }
+
+ class object {
+ open public fun init(name : T?) : Identifier {
+ val __ = Identifier(name, false)
+ return __
+ }
+ }
+}
+
+fun box() : String {
+ var i3 : Identifier<*>? = Identifier.init("name")
+ System.out?.println("Hello, " + i3?.getName())
+ return "OK"
+}
diff --git a/compiler/testData/compiler/smoke/Smoke.kt b/compiler/testData/compiler/smoke/Smoke.kt
index 6da801d1fde..d41ccce56b7 100644
--- a/compiler/testData/compiler/smoke/Smoke.kt
+++ b/compiler/testData/compiler/smoke/Smoke.kt
@@ -1,4 +1,7 @@
namespace Smoke
+import std.io.*
+
fun main(args: Array) {
+ print(args)
}
diff --git a/compiler/testData/psi/NewLinesValidOperations.jet b/compiler/testData/psi/NewLinesValidOperations.jet
new file mode 100644
index 00000000000..1a9483d7f62
--- /dev/null
+++ b/compiler/testData/psi/NewLinesValidOperations.jet
@@ -0,0 +1,11 @@
+fun test() {
+ val str = ""
+
+ str
+
+ .length
+
+ str
+
+ ?.length
+}
\ No newline at end of file
diff --git a/compiler/testData/psi/NewLinesValidOperations.txt b/compiler/testData/psi/NewLinesValidOperations.txt
new file mode 100644
index 00000000000..22e86010779
--- /dev/null
+++ b/compiler/testData/psi/NewLinesValidOperations.txt
@@ -0,0 +1,41 @@
+JetFile: NewLinesValidOperations.jet
+ NAMESPACE
+ FUN
+ PsiElement(fun)('fun')
+ PsiWhiteSpace(' ')
+ PsiElement(IDENTIFIER)('test')
+ VALUE_PARAMETER_LIST
+ PsiElement(LPAR)('(')
+ PsiElement(RPAR)(')')
+ PsiWhiteSpace(' ')
+ BLOCK
+ PsiElement(LBRACE)('{')
+ PsiWhiteSpace('\n ')
+ PROPERTY
+ PsiElement(val)('val')
+ PsiWhiteSpace(' ')
+ PsiElement(IDENTIFIER)('str')
+ PsiWhiteSpace(' ')
+ PsiElement(EQ)('=')
+ PsiWhiteSpace(' ')
+ STRING_TEMPLATE
+ PsiElement(OPEN_QUOTE)('"')
+ PsiElement(CLOSING_QUOTE)('"')
+ PsiWhiteSpace('\n\n ')
+ DOT_QUALIFIED_EXPRESSION
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('str')
+ PsiWhiteSpace('\n\n ')
+ PsiElement(DOT)('.')
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('length')
+ PsiWhiteSpace('\n\n ')
+ SAFE_ACCESS_EXPRESSION
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('str')
+ PsiWhiteSpace('\n\n ')
+ PsiElement(SAFE_ACCESS)('?.')
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('length')
+ PsiWhiteSpace('\n')
+ PsiElement(RBRACE)('}')
\ No newline at end of file
diff --git a/compiler/tests/compiler-tests.iml b/compiler/tests/compiler-tests.iml
index d1dadb8a16b..05bb0565855 100644
--- a/compiler/tests/compiler-tests.iml
+++ b/compiler/tests/compiler-tests.iml
@@ -11,6 +11,7 @@
+
diff --git a/compiler/tests/org/jetbrains/jet/codegen/CodegenTestCase.java b/compiler/tests/org/jetbrains/jet/codegen/CodegenTestCase.java
index 485a97b80d2..09f1485d650 100644
--- a/compiler/tests/org/jetbrains/jet/codegen/CodegenTestCase.java
+++ b/compiler/tests/org/jetbrains/jet/codegen/CodegenTestCase.java
@@ -1,6 +1,10 @@
package org.jetbrains.jet.codegen;
+import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.CharsetToolkit;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.JetLiteFixture;
import org.jetbrains.jet.lang.psi.JetFile;
@@ -9,6 +13,8 @@ import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
import org.jetbrains.jet.parsing.JetParsingTest;
import org.junit.Assert;
+import java.io.File;
+import java.io.FilenameFilter;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
diff --git a/compiler/tests/org/jetbrains/jet/codegen/ObjectGenTest.java b/compiler/tests/org/jetbrains/jet/codegen/ObjectGenTest.java
index 05c5a66ca93..d8eb251833e 100644
--- a/compiler/tests/org/jetbrains/jet/codegen/ObjectGenTest.java
+++ b/compiler/tests/org/jetbrains/jet/codegen/ObjectGenTest.java
@@ -25,4 +25,8 @@ public class ObjectGenTest extends CodegenTestCase {
public void testKt560() throws Exception {
blackBoxFile("regressions/kt560.jet");
}
+
+ public void testKt640() throws Exception {
+ blackBoxFile("regressions/kt640.jet");
+ }
}
diff --git a/compiler/tests/org/jetbrains/jet/codegen/StdlibTest.java b/compiler/tests/org/jetbrains/jet/codegen/StdlibTest.java
index 7337274caac..cd1bb67e1c3 100644
--- a/compiler/tests/org/jetbrains/jet/codegen/StdlibTest.java
+++ b/compiler/tests/org/jetbrains/jet/codegen/StdlibTest.java
@@ -6,6 +6,7 @@ import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
+import org.jetbrains.jet.compiler.CompileEnvironment;
import org.jetbrains.jet.compiler.CompileSession;
import org.jetbrains.jet.lang.psi.JetNamespace;
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
@@ -30,8 +31,8 @@ public class StdlibTest extends CodegenTestCase {
session.addSources(myFile.getVirtualFile());
try {
- session.addSources(addStdLib());
- } catch (IOException e) {
+ session.addStdLibSources();
+ } catch (Throwable e) {
throw new RuntimeException(e);
}
@@ -45,9 +46,9 @@ public class StdlibTest extends CodegenTestCase {
protected ClassFileFactory generateClassesInFile() {
try {
CompileSession session = new CompileSession(myEnvironment);
-
+ CompileEnvironment.initializeKotlinRuntime(myEnvironment);
session.addSources(myFile.getVirtualFile());
- session.addSources(addStdLib());
+ session.addStdLibSources();
if (!session.analyze(System.out)) {
return null;
@@ -57,18 +58,11 @@ public class StdlibTest extends CodegenTestCase {
} catch (RuntimeException e) {
System.out.println(generateToText());
throw e;
- } catch (IOException e) {
+ } catch (Throwable e) {
throw new RuntimeException(e);
}
}
- private VirtualFile addStdLib() throws IOException {
- String text = FileUtil.loadFile(new File(JetParsingTest.getTestDataDir() + "/../../stdlib/ktSrc/StandardLibrary.kt"), CharsetToolkit.UTF8).trim();
- text = StringUtil.convertLineSeparators(text);
- PsiFile stdLibFile = createFile("StandardLibrary.kt", text);
- return stdLibFile.getVirtualFile();
- }
-
public void testInputStreamIterator () {
blackBoxFile("inputStreamIterator.jet");
// System.out.println(generateToText());
@@ -85,4 +79,16 @@ public class StdlibTest extends CodegenTestCase {
public void testKt528 () {
blackBoxFile("regressions/kt528.kt");
}
+
+ public void testCollectionSize () throws Exception {
+ loadText("import std.util.*; fun box() = if(java.util.Arrays.asList(0, 1, 2)?.size == 3) \"OK\" else \"fail\"");
+// System.out.println(generateToText());
+ blackBox();
+ }
+
+ public void testCollectionEmpty () throws Exception {
+ loadText("import std.util.*; fun box() = if(java.util.Arrays.asList(0, 1, 2)?.empty ?: false) \"OK\" else \"fail\"");
+// System.out.println(generateToText());
+ blackBox();
+ }
}
diff --git a/compiler/tests/org/jetbrains/jet/compiler/CompileEnvironmentTest.java b/compiler/tests/org/jetbrains/jet/compiler/CompileEnvironmentTest.java
index 4b01efe9efd..520dee18d48 100644
--- a/compiler/tests/org/jetbrains/jet/compiler/CompileEnvironmentTest.java
+++ b/compiler/tests/org/jetbrains/jet/compiler/CompileEnvironmentTest.java
@@ -3,20 +3,20 @@ package org.jetbrains.jet.compiler;
import jet.modules.IModuleBuilder;
import jet.modules.IModuleSetBuilder;
import junit.framework.TestCase;
+import org.jetbrains.jet.cli.KotlinCompiler;
import org.jetbrains.jet.codegen.ClassFileFactory;
import org.jetbrains.jet.parsing.JetParsingTest;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.IOException;
+import java.io.*;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
/**
* @author yole
+ * @author alex.tkachman
*/
public class CompileEnvironmentTest extends TestCase {
private CompileEnvironment environment;
@@ -51,7 +51,58 @@ public class CompileEnvironmentTest extends TestCase {
assertTrue(entries.contains("Smoke/namespace.class"));
}
- private List listEntries(JarInputStream is) throws IOException {
+ public void testSmokeWithCompilerJar() throws IOException {
+ File tempFile = File.createTempFile("compilerTest", "compilerTest");
+ try {
+ KotlinCompiler.main(Arrays.asList("-module", JetParsingTest.getTestDataDir() + "/compiler/smoke/Smoke.kts", "-jar", tempFile.getAbsolutePath()).toArray(new String[0]));
+ FileInputStream fileInputStream = new FileInputStream(tempFile);
+ try {
+ JarInputStream is = new JarInputStream(fileInputStream);
+ try {
+ final List entries = listEntries(is);
+ assertTrue(entries.contains("Smoke/namespace.class"));
+ assertEquals(1, entries.size());
+ }
+ finally {
+ is.close();
+ }
+ }
+ finally {
+ fileInputStream.close();
+ }
+ }
+ finally {
+ tempFile.delete();
+ }
+ }
+
+ private static boolean delete(File file) {
+ boolean success = true;
+ if(file.isDirectory()) {
+ for (File child : file.listFiles()) {
+ success = success && delete(child);
+ }
+ }
+
+ return file.delete() && success;
+ }
+
+ public void testSmokeWithCompilerOutput() throws IOException {
+ File tempFile = File.createTempFile("compilerTest", "compilerTest");
+ tempFile.delete();
+ tempFile = new File(tempFile.getAbsolutePath());
+ tempFile.mkdir();
+ try {
+ KotlinCompiler.main(Arrays.asList("-src", JetParsingTest.getTestDataDir() + "/compiler/smoke/Smoke.kt", "-output", tempFile.getAbsolutePath()).toArray(new String[0]));
+ assertEquals(1, tempFile.listFiles().length);
+ assertEquals(1, tempFile.listFiles()[0].listFiles().length);
+ }
+ finally {
+ delete(tempFile);
+ }
+ }
+
+ private static List listEntries(JarInputStream is) throws IOException {
List entries = new ArrayList();
while (true) {
final JarEntry jarEntry = is.getNextJarEntry();
diff --git a/grammar/src/when.grm b/grammar/src/when.grm
index d6769712963..4b0dd363a83 100644
--- a/grammar/src/when.grm
+++ b/grammar/src/when.grm
@@ -18,7 +18,6 @@ whenEntry
whenCondition
: expression
- : ("." | "?.") postfixUnaryExpression typeArguments? valueArguments?
: ("in" | "!in") expression
: ("is" | "!is") isRHS
;
diff --git a/idea/src/org/jetbrains/jet/plugin/run/JetRunConfiguration.java b/idea/src/org/jetbrains/jet/plugin/run/JetRunConfiguration.java
index b84b0f8af04..ac0d9be5ae1 100644
--- a/idea/src/org/jetbrains/jet/plugin/run/JetRunConfiguration.java
+++ b/idea/src/org/jetbrains/jet/plugin/run/JetRunConfiguration.java
@@ -13,7 +13,6 @@ import com.intellij.openapi.options.SettingsEditor;
import com.intellij.openapi.util.DefaultJDOMExternalizer;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.WriteExternalException;
-import com.intellij.openapi.util.text.StringUtil;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
@@ -143,28 +142,35 @@ public class JetRunConfiguration extends ModuleBasedConfiguration.size : Int
+ get() = size()
+
+ val Collection<*>.empty : Boolean
+ get() = isEmpty()
+}
\ No newline at end of file
diff --git a/stdlib/ktSrc/StandardLibrary.kt b/stdlib/ktSrc/StandardLibrary.kt
index 53d594e313a..999cecbad2c 100644
--- a/stdlib/ktSrc/StandardLibrary.kt
+++ b/stdlib/ktSrc/StandardLibrary.kt
@@ -1,15 +1,5 @@
namespace std
-namespace util {
- import java.util.*
-
- val Collection.size : Int
- get() = size()
-
- val Collection.empty : Boolean
- get() = isEmpty()
-}
-
namespace io {
import java.io.*
import java.nio.charset.*