Example #1
0
        public LocalizedAssemblyView GetOrImportAssembly(ParserContext parser, Token throwToken, string fullImportNameWithDots)
        {
            LocalizedAssemblyView asmView = this.GetOrImportAssemblyImpl(parser, throwToken, fullImportNameWithDots);

            if (asmView != null && asmView.Scope != parser.CurrentScope)
            {
                parser.CurrentScope.AddDependency(throwToken, asmView);
            }
            return(asmView);
        }
Example #2
0
 public void AddDependency(Token throwToken, LocalizedAssemblyView view)
 {
     if (this.dependenciesAndViews.ContainsKey(view.Scope))
     {
         if (this.dependenciesAndViews[view.Scope] != view)
         {
             throw ParserException.ThrowException(
                       view.Locale,
                       ErrorMessages.CANNOT_IMPORT_SAME_LIBRARY_FROM_DIFFERENT_LOCALES,
                       throwToken);
         }
     }
     this.dependenciesAndViews[view.Scope] = view;
     this.Metadata.RegisterDependencies(view.Scope.Metadata);
 }
Example #3
0
        public void ParseFile(string filename, string code)
        {
            FileScope fileScope = new FileScope(filename, code, this.CurrentScope, this.GetNextFileId());

            this.RegisterFileUsed(fileScope, code);
            TokenStream tokens = new TokenStream(fileScope);

            List <string> namespaceImportsBuilder = new List <string>();

            // Implicitly import the Core library for the current locale.
            LocalizedAssemblyView implicitCoreImport = this.ScopeManager.GetCoreLibrary(this);

            namespaceImportsBuilder.Add(implicitCoreImport.Name);
            fileScope.Imports.Add(new ImportStatement(null, implicitCoreImport.Name, fileScope));

            while (tokens.HasMore &&
                   (tokens.IsNext(this.Keywords.IMPORT) ||
                    (this.IsCSharpCompat && tokens.IsNext("using"))))
            {
                ImportStatement importStatement = this.TopLevelParser.ParseImport(tokens, fileScope);
                if (importStatement == null)
                {
                    throw new Exception();
                }
                namespaceImportsBuilder.Add(importStatement.ImportPath);
                LocalizedAssemblyView localizedAssemblyView = this.ScopeManager.GetOrImportAssembly(this, importStatement.FirstToken, importStatement.ImportPath);
                if (localizedAssemblyView == null)
                {
                    this.unresolvedImports.Add(importStatement);
                }
            }

            string[] namespaceImports = namespaceImportsBuilder.ToArray();

            while (tokens.HasMore)
            {
                this.CurrentScope.AddExecutable(this.TopLevelParser.Parse(tokens, null, fileScope));
            }
        }
Example #4
0
        private LocalizedAssemblyView GetOrImportAssemblyImpl(ParserContext parser, Token throwToken, string fullImportNameWithDots)
        {
            // TODO: allow importing from a user-specified locale
            Locale fromLocale = parser.CurrentLocale;
            string name       = fullImportNameWithDots.Contains('.') ? fullImportNameWithDots.Split('.')[0] : fullImportNameWithDots;

            string           secondAttemptedKey = name;
            AssemblyMetadata assemblyMetadata   = this.assemblyFinder.GetAssemblyMetadataFromAnyPossibleKey(fromLocale.ID + ":" + name);
            Locale           effectiveLocale    = fromLocale;

            if (assemblyMetadata == null)
            {
                assemblyMetadata = this.assemblyFinder.GetAssemblyMetadataFromAnyPossibleKey(name);
                if (assemblyMetadata != null &&
                    assemblyMetadata.SupportedLocales.Contains(fromLocale) &&
                    assemblyMetadata.InternalLocale != fromLocale)
                {
                    // Coincidental cross-language collision.
                    return(null);
                }

                if (assemblyMetadata == null)
                {
                    // Simply no matches at all.
                    return(null);
                }

                effectiveLocale = assemblyMetadata.InternalLocale;
            }

            // Are there any restrictions on importing that library from this location?
            if (!assemblyMetadata.IsAllowedImport(parser.CurrentLibrary))
            {
                throw new ParserException(throwToken, "This library cannot be imported from here.");
            }

            // Ensure all secondary lookups for each locale is instantiated to make the upcoming code more readable.
            if (!this.importedAssembliesByLocalizedName.ContainsKey(effectiveLocale))
            {
                this.importedAssembliesByLocalizedName[effectiveLocale] = new Dictionary <string, LocalizedAssemblyView>();
            }
            if (!this.importedAssembliesByLocalizedName.ContainsKey(assemblyMetadata.InternalLocale))
            {
                this.importedAssembliesByLocalizedName[assemblyMetadata.InternalLocale] = new Dictionary <string, LocalizedAssemblyView>();
            }

            // Check to see if this library has been imported before.
            if (this.importedAssembliesById.ContainsKey(assemblyMetadata.ID))
            {
                // Is it imported by the same locale?
                if (this.importedAssembliesByLocalizedName[effectiveLocale].ContainsKey(name))
                {
                    // Then just return the previous instance as-is.
                    return(this.importedAssembliesByLocalizedName[effectiveLocale][name]);
                }

                // Wrap the previous instance in the new locale.
                LocalizedAssemblyView output = new LocalizedAssemblyView(effectiveLocale, this.importedAssembliesById[assemblyMetadata.ID]);
                this.importedAssembliesByLocalizedName[effectiveLocale][output.Name] = output;
                return(output);
            }

            // If the assembly exists but hasn't been imported before, instantiate it and
            // add it to all the lookups. This needs to happen before parsing the embedded
            // code to prevent infinite recursion.
            CompilationScope compilationScope = new CompilationScope(parser.BuildContext, assemblyMetadata);

            this.assembliesAlreadyImportedIndexByKey[assemblyMetadata.CanonicalKey] = this.ImportedAssemblyScopes.Count;
            this.ImportedAssemblyScopes.Add(compilationScope);
            this.importedAssembliesById[assemblyMetadata.ID] = compilationScope;
            LocalizedAssemblyView localizedView = new LocalizedAssemblyView(effectiveLocale, compilationScope);

            this.importedAssembliesByLocalizedName[effectiveLocale][name] = localizedView;

            // Parse the assembly.
            parser.PushScope(compilationScope);
            Dictionary <string, string> sourceCode = assemblyMetadata.GetSourceCode();

            foreach (string file in sourceCode.Keys.OrderBy(s => s.ToLowerInvariant()))
            {
                string fakeName = "[" + file + "]";
                string code     = sourceCode[file];
                parser.ParseFile(fakeName, code);
            }
            parser.PopScope();

            return(localizedView);
        }